Greasy Fork

chatGPT tools Plus(修改版)

chatGPT free version(修改版),Google、必应、百度侧边栏Chat搜索,即刻体验AI,无需翻墙,无需注册,无需等待!

目前为 2023-03-15 提交的版本。查看 最新版本

// ==UserScript==
// @name         chatGPT tools Plus(修改版)
// @namespace    http://tampermonkey.net/
// @version      1.0.8
// @description  chatGPT free version(修改版),Google、必应、百度侧边栏Chat搜索,即刻体验AI,无需翻墙,无需注册,无需等待!
// @author       夜雨
// @match        https://cn.bing.com/*
// @match        https://www.bing.com/*
// @match      https://chat.openai.com/chat
// @match      https://www.google.com/*
// @match      http*://www.baidu.com/s*
// @match      https://www.baidu.com*
// @match      https://www.google.com.hk/*
// @include    /^https:\/\/www\.baidu\.com\/s\?wd.*$/
// @icon         https://www.google.com/s2/favicons?sz=64&domain=openai.com
// @grant       GM_xmlhttpRequest
// @grant       GM_addStyle
// @run-at     document-end
// @require    https://cdn.staticfile.org/jquery/3.4.0/jquery.min.js
// @require    https://cdn.staticfile.org/jquery-cookie/1.4.1/jquery.cookie.min.js
// @require    https://cdn.jsdelivr.net/npm/[email protected]/marked.min.js
// @require    https://cdnjs.cloudflare.com/ajax/libs/markdown-it/13.0.1/markdown-it.min.js
// @require    https://unpkg.com/axios/dist/axios.min.js
// @connect   ip-api.com
// @connect   chat.openai.com
// @connect   gpt.chatapi.art
// @connect   api.forchange.cn
// @connect    wenxin110.top
// @connect    chatforai.com
// @license    MIT
// @resource css https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.1.0/github-markdown.css
// @resource css https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css
// @require    https://cdn.jsdelivr.net/npm/[email protected]/dist/showdown.min.js
// @require    https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js
// @require    https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js


// ==/UserScript==

(function() {
		'use strict';
		// @require    https://cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.8.0/highlightjs-line-numbers.min.js

		//重要声明:感谢隔壁作者:zhengbangbo (https://github.com/zhengbangbo/chat-gpt-userscript)的请求处理方式,之前一直不知道怎么处理SSE响应,原来直接就可以用一般的方式来接收,那么对返回数据处理切割就直接借鉴啦!(反正MIT不是嘛)
		//cookie 大家自己想办法弄到,别霍霍我了呜呜
		//对返回结果增加了markdown解析成html

		//请在上面添加一句:油猴因为策略问题没法增加这个js
		//多亏了zhengbangbo大佬,现在已经解决这个策略问题了!
		// @require    https://cdn.jsdelivr.net/npm/marked/marked.min.js

		//enc-start
		async function digestMessage(r) {
			const hash = CryptoJS.SHA256(r);
			return hash.toString(CryptoJS.enc.Hex);
		}

		const generateSignature = async r => {
			const {
				t: e,
				m: t
			} = r;
			const n = {}.PUBLIC_SECRET_KEY;
			const a = `${e}:${t}:${n}`;
			return await digestMessage(a);
		};
		//enc-end

		//start


		function addChatBtn() {

			let mybtn =
				`<span class="bg s_btn_wr"><input type="button" id="mybtn" value="加载chat" class="bg s_btn"></span>`;
			$(".bg.s_btn_wr").append(mybtn)
			document.getElementById("mybtn").addEventListener("click", function() {
				console.log("reloadPage")
				if (window.location.href.indexOf("https:\/\/www.baidu.com\/s") > -1) {
					GM_add_box_style(2)
					addBothStyle()
					keyEvent()
					appendBox(2).then((res) => {
						pivElemAddEventAndValue(2)
					})
				}
			})
		}


		//end

		//顶级配置
		//可以手动配置your_cookie!
		const requestUrl = `https://gpt.chatapi.art/backend-api/conversation`
		var your_qus
		var abortXml
		if (window.location.href.indexOf("bing.com") > -1) {
			getYourCookie()
			GM_add_box_style(0)
			addBothStyle()
			keyEvent()
			appendBox(0).then((res) => {
				pivElemAddEventAndValue(0)
			})
			linkToBing_beautification_script()
		}
		if (window.location.href.indexOf("www.google.com") > -1) {
			GM_add_box_style(1)
			addBothStyle()
			keyEvent()
			appendBox(1).then((res) => {
				pivElemAddEventAndValue(1)
			})
		}
		if (window.location.href.indexOf("https:\/\/www.baidu.com\/s") > -1) {
			GM_add_box_style(2)
			addBothStyle()
			keyEvent()
			appendBox(2).then((res) => {
				pivElemAddEventAndValue(2)
			})
		} else if (window.location.href.indexOf("https:\/\/www.baidu.com") > -1) {
			addChatBtn()
		}

		if (window.location.href.indexOf("chat.openai.com") > -1) {
			//$.cookie('yourCookie','dumplings', {domain:'qq.com',path:'/'});
			console.log("httpOnly保护,没法拿到cookie,自己复制粘贴控制台")
		}
		//顶级函数
		function uuid() { //uuid 产生
			var s = [];
			var hexDigits = "0123456789abcdef";
			for (var i = 0; i < 36; i++) {
				s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
			}
			s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
			s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
			s[8] = s[13] = s[18] = s[23] = "-";

			var uuid = s.join("");
			return uuid;
		}

		function GM_add_box_style(case_web) {
			switch (case_web) {
				case 0: //bing
					GM_addStyle(`
    #gptAnswer{
   margin: 15px;
   border-top: solid;
    border-bottom: solid;
    }
    #gptInput{
    width:74%;
    border-radius: 4px;
    }
    #gptInputBox{
        display: flex;
    justify-content: space-around;
    }

    #button_GPT:hover{
    background:#ffffffcc;
    }
    #gptDiv{
     border-radius: 8px;
    padding: 10px;
    margin-bottom: 9px;
    width:452px;
    translate:-20px;
    background:#ffffffcc;
    backdrop-filter: blur(5px);
    display: flex;
    flex-direction: column;
    }
    #button_GPT{
    }
    #button_GPT{
    background: transparent;
    border-radius: 4px;

    }
    #gptCueBox{
        translate: 3px;
    }

	 p{white-space: pre-line}


    `)
					break;
				case 1: //google
					GM_addStyle(`
    #gptAnswer{
   margin: 15px;
   border-top: solid;
    border-bottom: solid;
    }
    #gptInput{
    border-radius: 4px;
    width: 68%;
    }
    #button_GPT:hover{
    background:#dcdcdccc;
    }
    #gptDiv{
		width:452px;
        flex: 1;
    display: flex;
    flex-direction: column;
    height: fit-content;

    }
    #gptInputBox{
    display:flex;
    justify-content: space-around;
    }
    #button_GPT{
    background: transparent;
    border-radius: 3px;
     font-size: 14px;
    }
    #gptStatus{
        margin-left: 7px;
        }


 p{white-space: pre-line}


    `)
					break; //baidu
				case 2:
					GM_addStyle(`
    #gptAnswer{
   margin: 15px;
   border-top: solid;
    border-bottom: solid;
    }
    #gptInput{
    border-radius: 4px;
    width: 68%;
    }
    #button_GPT:hover{
    background:#dcdcdccc;
    }
    #gptDiv{
	 width:452px;
    flex: 1;
    display: flex;
    flex-direction: column;
    height: fit-content;

    }
    #gptInputBox{
    display:flex;
    justify-content: space-around;
    }
    #button_GPT{
    background: transparent;
    border-radius: 3px;
     font-size: 14px;
    }
    #gptStatus{
        margin-left: 7px;
        }

    p{white-space: pre-line}

    `)
					break;
				default:
					alert("参数没设定")
			}

		}

		function do_it() {
			let finalResult
			let normalArray
			let nowResult
			document.getElementById('gptAnswer').innerHTML = `<div>加载中<span id="dot"></span></div>`;


			const now = Date.now();
			console.log(now);

			generateSignature({
				t: now,
				m: your_qus || ""
			}).then(sign => {
				console.log(sign)
				abortXml = GM_xmlhttpRequest({
					method: "POST",
					//url: "https://chat.openai.com/backend-api/conversation",
					url: "https://chatforai.com/api/generate",
					headers: {
						"Content-Type": "application/json"
						//  Authorization: `Bearer `,
					},
					data: JSON.stringify({
						messages: [{
							role: "user",
							content: your_qus
						}],
						time: now,
						pass: null,
						sign: sign
					}),
					//	data: JSON.stringify({
					//	prompt: "Human:"+your_qus+"\nAI:",
					//		tokensLength: your_qus.length
					//	}),

					onload: function(res) {
						if (res.status === 200) {
							console.log('成功....')
							console.log(res.response)
							let rest = res.response
							//console.log(rest.choices[0].text.replaceAll("\n","</br>"))

							try {
								log(mdConverter(rest.replaceAll(/\\n+/g, "\n")))
								document.getElementById('gptAnswer').innerHTML =
									`${mdConverter(rest.replaceAll(/\\n+/g,"\n"))}`
							} catch (e) {
								//TODO handle the exception
								document.getElementById('gptAnswer').innerHTML = `${rest}`
							}

							for (let i = 0; i <= document.getElementsByTagName("code").length -
								1; i++) {
								document.getElementsByTagName("code")[i].setAttribute("class",
									"language-javascript hljs");
								hljs.highlightAll() //奇怪,为什么不行
							}
						} else {
							console.log('失败')
							console.log(res)
							document.getElementById('gptAnswer').innerHTML = '访问失败了'
						}
					},

				 responseType: "application/json;charset=UTF-8",

					onprogress: function(msg) {
						//console.log(msg) //Todo
					},
					onerror: function(err) {
				  document.getElementById('gptAnswer').innerHTML =
							`<div>some err happends,errinfo :<br>${err}</div>`
					},
					ontimeout: function(err) {
						document.getElementById('gptAnswer').innerHTML =
							`<div>Opps!TimeOut,Please try again,errinfo:<br>${err}</div>`
					}
				});
			});

		}




			function creatBox() {
				return new Promise((resolve) => {
					var divE = document.createElement('div');
					var divId = document.createAttribute("id"); //创建属性
					divId.value = 'gptDiv'; //设置属性值
					divE.setAttributeNode(divId); //给div添加属性
					var pE = document.createElement('p');
					var pClass = document.createAttribute('class');
					pClass.value = 'textClass';
					pE.setAttributeNode(pClass)
					var pText = document.createTextNode("chatGPT tools Plus 已启动");
					pE.appendChild(pText);
					divE.appendChild(pE);
					divE.innerHTML = `
    <div id="gptInputBox">
    <input id="gptInput" type=text><button id="button_GPT" >chat一下</button>
    </div>
    <div id=gptCueBox>
    <p id="gptStatus">&nbsp openAI 已就绪,请输入你的问题</p>
   <article id="gptAnswer" class="markdown-body"><div id="gptAnswer_inner">chatGPT tools Plus 已启动<div></article>
    </div><p></p>`
					resolve(divE)
				})
			}
			async function pivElemAddEventAndValue(append_case) {
				var search_content

				if (append_case === 2) {
					search_content = document.getElementById('kw').value
				}
				if (append_case === 1) {
					search_content = document.querySelector(
						"#tsf > div:nth-child(1) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input:nth-child(3)"
					).value
				}
				if (append_case === 0) {
					search_content = document.getElementsByClassName('b_searchbox')[0].value
				}
				document.getElementById("gptInput").value = search_content
				document.getElementById('button_GPT').addEventListener('click', () => {
					your_qus = document.getElementById("gptInput").value
					do_it()

				})


			}
			async function appendBox(append_case) {
				return new Promise((resolve, reject) => {
					creatBox().then((divE) => {
						switch (append_case) {
							case 0: //bing
								if (divE) {
									document.getElementById('b_context').prepend(divE)
								}
								break;
							case 1: //google
								if (document.getElementsByClassName('TQc1id ')[0]) {
									document.getElementsByClassName('TQc1id ')[0].prepend(divE);
								} else {
									document.getElementById("rcnt").appendChild(divE);
								}
								break;
							case 2:
								if (document.getElementById('content_right')) {
									document.getElementById('content_right').prepend(divE)
								}
								break;
							default:
								if (divE) {
									console.log(`啥情况${divE}`)
								}
						}
					}).catch((err) => {
						throw new Error(err)
					})

					resolve("finished")
				})
			}
			//焦点函数
			function isBlur() {
				var myInput = document.getElementById('gptInput');
				if (myInput == document.activeElement) {
					return 1
				} else {
					return 0
				}
			}

			function keyEvent() {
				document.onkeydown = function(e) {
					var keyNum = window.event ? e.keyCode : e.which;
					if (13 == keyNum) {
						if (isBlur()) {
							document.getElementById('button_GPT').click()
						} else {
							console.log("失焦不执行")
						}

					}
				}

			}

			function checkIp() {
				GM_xmlhttpRequest({
					method: "GET",
					url: "http://ip-api.com/json/",
					onloadend: function(data) {
						if (data) {
							try {
								data = JSON.parse(data.response)
							} catch (err) {
								console.log(err)
							}
							console.log(data.country)
							if (data.country == "Hong Kong") {
								document.getElementById('gptStatus').innerHTML = `&nbsp openAI 已就绪,请输入你的问题`
							}
						} else {
							document.getElementById('gptStatus').innerHTML = `&nbsp openAI 就绪`
							throw new Error('Error while executing the code');
						}
					},
					onerror: function(err) {
						document.getElementById('gptStatus').innerHTML = `&nbsp openAI 就绪`
						throw new Error('Error while executing the code');
					},
					ontimeout: function(err) {
						document.getElementById('gptStatus').innerHTML = `&nbsp openAI 就绪`
						throw new Error('Error while executing the code');
					}
				})
			}

			function addBothStyle() {
				GM_addStyle(`
        #dot{
    height: 4px;
    width: 4px;
    display: inline-block;
    border-radius: 2px;
    animation: dotting 2.4s  infinite step-start;
}
  @keyframes dotting {
    25%{
        box-shadow: 4px 0 0 #71777D;
    }
    50%{
        box-shadow: 4px 0 0 #71777D ,14px 0 0 #71777D;
    }
    75%{
        box-shadow: 4px 0 0 #71777D ,14px 0 0 #71777D, 24px 0 0 #71777D;
    }
}
 pre{
     overflow-x: scroll;
      overflow-y: hidden;
     background: #fffaec;
    border-radius: 4px;
    padding: 14px 3px;
 }
 pre::-webkit-scrollbar {
 }
    `)
			}

			function getYourCookie() {
				GM_xmlhttpRequest({
					method: "GET",
					url: "https://chat.openai.com/api/auth/session",
					onloadend: function(data) {
						if (data) {
							data = JSON.parse(data.response)
							console.log(data.accessToken)
							//     window.document.cookie=`your_cookie=${data.accessToken};expire:1000*60*60*24`
							setCookie("your_cookie", data.accessToken, 1)
						}
					},
					onerror: function(err) {
						throw new Error('Error while executing the code');

					},
					ontimeout: function(err) {
						throw new Error('Error while executing the code');
					}
				})


			}

			function setCookie(cname, cvalue, exdays) {
				var d = new Date();
				d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
				var expires = "expires=" + d.toGMTString();
				document.cookie = cname + "=" + cvalue + "; " + expires;
			}
			//原生cookie函数
			function getCookieObject() {
				let cookieString = document.cookie;
				cookieString = cookieString.substring(0, cookieString.length - 1);
				let tempCookieArray = cookieString.split('; ');

				let cookieObject = {}; // 存放 cookie 键值对

				tempCookieArray.forEach(item => {
					let name = item.substring(0, item.indexOf('='));
					let value = item.substring(item.indexOf('=') + 1);
					value = decodeURIComponent(value); // 还原字符串
					cookieObject[name] = value; // 将键值插入中这个对象中
				});

				return cookieObject // 返回包含 cookie 键值对的对象
			}

			function sendModerations() {
				GM_xmlhttpRequest({
					method: "POST",
					url: requestUrl,
					headers: {
						"Content-Type": "application/json",
						Authorization: `Bearer ${your_cookie}`,
					},
					data: JSON.stringify({
						input: getCookieObject().preQuesAns,
						model: "text-moderation-playground"
					}),
					onloadend: function(data) {
						console.log(data)
					},
					onerror: function(err) {
						throw new Error('Error while executing the code');

					},
					ontimeout: function(err) {
						throw new Error('Error while executing the code');
					}
				})


			}

			function autoClick() {
				document.getElementById('button_GPT').click()
			}

			function linkToBing_beautification_script() {

				if (getCookieObject.blurDeg && getCookieObject.aDeg1 && getCookieObject.aDeg2) {
					document.getElementById('gptDiv').style.background = `#ffffff${getCookieObject.aDeg2}`
					document.getElementById('gptDiv').style.backdropFilter = `${getCookieObject.blurDeg}`
				}
			}

			function creatBox_and_addEventlis(append_case) {
				var divE = document.createElement('div');
				var divId = document.createAttribute("id"); //创建属性
				divId.value = 'gptDiv'; //设置属性值
				divE.setAttributeNode(divId); //给div添加属性
				var pE = document.createElement('p');
				var pClass = document.createAttribute('class');
				pClass.value = 'textClass';
				pE.setAttributeNode(pClass)
				var pText = document.createTextNode("chatGPT tools Plus 已启动");
				pE.appendChild(pText);
				divE.appendChild(pE);
				switch (append_case) {
					case 0:
						if (divE) {
							document.getElementById('b_context').prepend(divE)
						}
						break;
					case 1:
						if (document.getElementsByClassName('TQc1id ')[0]) {
							document.getElementsByClassName('TQc1id ')[0].prepend(divE);
						} else {
							document.getElementById("rcnt").appendChild(divE);
						}
						break;
					case 2:
						if (document.getElementById('content_right')) {
							document.getElementById('content_right').prepend(divE)
						}
						break;
					default:
						if (divE) {
							document.getElementById('b_context').prepend(divE)
						}
				}
				document.getElementById('gptDiv').innerHTML =
					`<div id="gptInputBox"><input id="gptInput"type=text><button id="button_GPT">chat一下</button></div><div id=gptCueBox><p id="gptStatus">&nbsp openAI已就绪,请输入你的问题</p><div id="gptAnswer">chatGPT tools Plus 免费版已启动</div></div><p></p>`
				var search_content
				if (append_case === 2) {
					search_content = document.getElementById('kw').value
				}
				if (append_case === 1) {
					search_content = document.querySelector(
							"#tsf > div:nth-child(1) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input:nth-child(3)")
						.value
				}
				if (append_case === 0) {
					search_content = document.getElementsByClassName('b_searchbox')[0].value
				}
				document.getElementById("gptInput").value = search_content
				document.getElementById('button_GPT').addEventListener('click', () => {
					your_qus = document.getElementById("gptInput").value
					do_it()

				})
			}

			function log(a) {
				console.log(a)
			}

			function Uint8ArrayToString(fileData) {
				var dataString = "";
				for (var i = 0; i < fileData.length; i++) {
					dataString += String.fromCharCode(fileData[i]);
				}

				return dataString
			}

			function decodeUnicode(str) {
				str = str.replace(/\\/g, "%");
				//转换中文
				str = unescape(str);
				//将其他受影响的转换回原来
				str = str.replace(/%/g, "\\");
				//对网址的链接进行处理
				str = str.replace(/\\/g, "");
				return str;
			}

			function mdConverter(rawData) {
				var converter = new showdown.Converter(); //增加拓展table
				converter.setOption('tables',
					true); //启用表格选项。从showdown 1.2.0版开始,表支持已作为可选功能移入核心拓展,showdown.table.min.js扩展已被弃用
				var view = converter.makeHtml(rawData);
				return view;
			}



		})();