chatGPT tools Plus ++ (cookie版)

chatGPT Google&必应&百度侧边栏自定义搜索(免翻墙,cookie登录版)

当前为 2022-12-12 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name chatGPT tools Plus ++ (cookie版)
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.3.2
  5. // @description chatGPT Google&必应&百度侧边栏自定义搜索(免翻墙,cookie登录版)
  6. // @author Onion
  7. // @match https://cn.bing.com/*
  8. // @match https://www.bing.com/*
  9. // @match https://chat.openai.com/chat
  10. // @match https://www.google.com/*
  11. // @match https://www.google.com.hk/*
  12. // @include /^https:\/\/www\.baidu\.com\/s\?wd.*$/
  13. // @icon https://www.google.com/s2/favicons?sz=64&domain=openai.com
  14. // @grant GM_xmlhttpRequest
  15. // @grant GM_addStyle
  16. // @require https://cdn.staticfile.org/jquery/3.4.0/jquery.min.js
  17. // @require https://cdn.staticfile.org/jquery-cookie/1.4.1/jquery.cookie.min.js
  18. // @require https://cdn.jsdelivr.net/npm/marked@4.2.3/marked.min.js
  19. // @require https://cdnjs.cloudflare.com/ajax/libs/markdown-it/13.0.1/markdown-it.min.js
  20. // @require https://unpkg.com/axios/dist/axios.min.js
  21. // @connect ip-api.com
  22. // @connect chat.openai.com
  23. // @connect gpt.chatapi.art
  24. // @license MIT
  25. // @resource css https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.1.0/github-markdown.css
  26. // @resource css https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/styles/default.min.css
  27. // @require https://cdn.jsdelivr.net/npm/showdown@2.1.0/dist/showdown.min.js
  28. // @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.7.0/highlight.min.js
  29.  
  30.  
  31. // ==/UserScript==
  32.  
  33. (function() {
  34. 'use strict';
  35. // @require https://cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.8.0/highlightjs-line-numbers.min.js
  36.  
  37. //重要声明:感谢隔壁作者:zhengbangbo (https://github.com/zhengbangbo/chat-gpt-userscript)的请求处理方式,之前一直不知道怎么处理SSE响应,原来直接就可以用一般的方式来接收,那么对返回数据处理切割就直接借鉴啦!(反正MIT不是嘛)
  38. //cookie 大家自己想办法弄到,别霍霍我了呜呜
  39. //对返回结果增加了markdown解析成html
  40.  
  41. //请在上面添加一句:油猴因为策略问题没法增加这个js
  42. //多亏了zhengbangbo大佬,现在已经解决这个策略问题了!
  43. // @require https://cdn.jsdelivr.net/npm/marked/marked.min.js
  44.  
  45.  
  46.  
  47. //顶级配置
  48. //可以手动配置your_cookie!
  49. const your_cookie=getCookieObject().your_cookie
  50. const requestUrl = `https://chat.openai.com/backend-api/moderations`
  51. var your_qus
  52. var abortXml
  53. if (window.location.href.indexOf("bing.com") > -1) {
  54. getYourCookie()
  55. GM_add_box_style(0)
  56. addBothStyle()
  57. keyEvent()
  58. appendBox(0).then((res)=>{pivElemAddEventAndValue(0)})
  59. linkToBing_beautification_script()
  60. }
  61. if (window.location.href.indexOf("www.google.com") > -1) {
  62. getYourCookie()
  63. GM_add_box_style(1)
  64. addBothStyle()
  65. keyEvent()
  66. appendBox(1).then((res)=>{pivElemAddEventAndValue(1)})
  67. }
  68. if (window.location.href.indexOf("https://www.baidu.com/s?wd") > -1) {
  69. getYourCookie()
  70. GM_add_box_style(2)
  71. addBothStyle()
  72. keyEvent()
  73. appendBox(2).then((res)=>{pivElemAddEventAndValue(2)})
  74. }
  75. if (window.location.href.indexOf("chat.openai.com") > -1) {
  76. //$.cookie('yourCookie','dumplings', {domain:'qq.com',path:'/'});
  77. getYourCookie()
  78. console.log("httpOnly保护,没法拿到cookie,自己复制粘贴控制台")
  79. }
  80. //顶级函数
  81. function uuid() { //uuid 产生
  82. var s = [];
  83. var hexDigits = "0123456789abcdef";
  84. for (var i = 0; i < 36; i++) {
  85. s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
  86. }
  87. s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
  88. s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
  89. s[8] = s[13] = s[18] = s[23] = "-";
  90.  
  91. var uuid = s.join("");
  92. return uuid;
  93. }
  94. function GM_add_box_style(case_web){
  95. switch (case_web){
  96. case 0://bing
  97. GM_addStyle(`
  98. #gptAnswer{
  99. margin: 15px;
  100. border-top: solid;
  101. border-bottom: solid;
  102. }
  103. #gptInput{
  104. width:74%;
  105. border-radius: 4px;
  106. }
  107. #gptInputBox{
  108. display: flex;
  109. justify-content: space-around;
  110. }
  111.  
  112. #button_GPT:hover{
  113. background:#ffffffcc;
  114. }
  115. #gptDiv{
  116. border-radius: 8px;
  117. padding: 10px;
  118. margin-bottom: 9px;
  119. width:452px;
  120. translate:-20px;
  121. background:#ffffffcc;
  122. backdrop-filter: blur(5px);
  123. display: flex;
  124. flex-direction: column;
  125. }
  126. #button_GPT{
  127. }
  128. #button_GPT{
  129. background: transparent;
  130. border-radius: 4px;
  131.  
  132. }
  133. #gptCueBox{
  134. translate: 3px;
  135. }
  136.  
  137.  
  138.  
  139. `)
  140. break;
  141. case 1: //google
  142. GM_addStyle(`
  143. #gptAnswer{
  144. margin: 15px;
  145. border-top: solid;
  146. border-bottom: solid;
  147. }
  148. #gptInput{
  149. border-radius: 4px;
  150. width: 68%;
  151. }
  152. #button_GPT:hover{
  153. background:#dcdcdccc;
  154. }
  155. #gptDiv{
  156. flex: 1;
  157. display: flex;
  158. flex-direction: column;
  159. height: fit-content;
  160.  
  161. }
  162. #gptInputBox{
  163. display:flex;
  164. justify-content: space-around;
  165. }
  166. #button_GPT{
  167. background: transparent;
  168. border-radius: 3px;
  169. font-size: 14px;
  170. }
  171. #gptStatus{
  172. margin-left: 7px;
  173. }
  174.  
  175.  
  176.  
  177.  
  178.  
  179. `)
  180. break;//baidu
  181. case 2:GM_addStyle(`
  182. #gptAnswer{
  183. margin: 15px;
  184. border-top: solid;
  185. border-bottom: solid;
  186. }
  187. #gptInput{
  188. border-radius: 4px;
  189. width: 68%;
  190. }
  191. #button_GPT:hover{
  192. background:#dcdcdccc;
  193. }
  194. #gptDiv{
  195. flex: 1;
  196. display: flex;
  197. flex-direction: column;
  198. height: fit-content;
  199.  
  200. }
  201. #gptInputBox{
  202. display:flex;
  203. justify-content: space-around;
  204. }
  205. #button_GPT{
  206. background: transparent;
  207. border-radius: 3px;
  208. font-size: 14px;
  209. }
  210. #gptStatus{
  211. margin-left: 7px;
  212. }
  213.  
  214.  
  215.  
  216. `)
  217. break;
  218. default :
  219. alert("参数没设定")
  220. }
  221.  
  222. }
  223. function do_it(){
  224. if(!your_cookie){
  225. document.getElementById('gptAnswer').innerHTML=`<div>你的cookie好像不见了!<a href="https://chat.openai.com">点我去登录获取</a></div>`
  226. }
  227. else{
  228.  
  229.  
  230. let finalResult
  231. let normalArray
  232. let nowResult
  233. document.getElementById('gptAnswer').innerHTML=`<div>加载中<span id="dot"></span></div>`
  234.  
  235. abortXml=GM_xmlhttpRequest({
  236. method: "POST",
  237. url: "https://chat.openai.com/backend-api/conversation",
  238. headers: {
  239. "Content-Type": "application/json",
  240. Authorization: `${your_cookie}`,
  241. },
  242. data: JSON.stringify({//抓包conversation就可以看到这个结构
  243. action: "next",
  244. messages: [
  245. {
  246. id: uuid(),
  247. role: "user",
  248. content: {
  249. content_type: "text",
  250. parts: [your_qus],
  251. },
  252. },
  253. ],
  254. model: "text-davinci-002-render",
  255. parent_message_id: uuid(),
  256. }),
  257. // onprogress: function(msg){console.log(msg)},
  258. // onreadystatechange:function(msg){log(msg)},
  259. onloadstart:(stream)=>{ //肝了好久,终于找到油猴接受SSE的接受方法了
  260. let result = "";
  261. const reader = stream.response.getReader();
  262. let charsReceived = 0;
  263. reader.read().then(function processText({ done, value }) {
  264. if (done) {
  265. if(finalResult==0){
  266. document.getElementById('gptAnswer').innerHTML=`<div>你的cookie好像过期了!<a href="https://chat.openai.com">点我去登录获取</a></div>`
  267. }
  268. else{
  269. document.getElementById('gptAnswer').innerHTML=`${mdConverter(decodeUnicode(finalResult.replace(/\\n+/g,"\n")))}`
  270. // document.querySelector("code").setAttribute("class", "language-javascript hljs");
  271. for(let i=0;i<=document.getElementsByTagName("code").length-1;i++){
  272. document.getElementsByTagName("code")[i].setAttribute("class", "language-javascript hljs");
  273. hljs.highlightAll()//奇怪,为什么不行
  274. }
  275. }
  276. return;
  277. }
  278.  
  279. charsReceived += value.length;
  280. const chunk = value;
  281. result += chunk;
  282. // log(JSON.stringify(chunk).replace(/\{/,"").replace(/\}/,""))
  283. normalArray=Array.from(chunk)
  284. // String.fromCharCode.apply(null, normalArray)
  285. nowResult=String.fromCharCode.apply(null, normalArray).match(/(?<=\[).*(?=\])/g)[0]
  286. // console.log(mdConverter(decodeUnicode(nowResult.replace(/\\n+/g,"<换行>"))))
  287. if(nowResult!=="DONE"){
  288. finalResult=nowResult
  289. }
  290.  
  291. // console.log(finalResult)
  292. document.getElementById('gptAnswer').innerHTML=`${mdConverter(decodeUnicode(finalResult.replace(/\\n+/g,"\n")))}`
  293. return reader.read().then(processText);
  294. });
  295. },
  296. responseType:"stream",
  297. /* onloadend: function (data) {
  298. var answer
  299. if (data.response) {
  300. var data_transform=data.response.split("\n\n")
  301. if(data_transform){
  302. try{
  303. data_transform=JSON.parse(data_transform.slice(-3,-2)[0].slice(6))
  304. answer=data_transform.message.content.parts[0]
  305. document.getElementById('gptAnswer').innerHTML=marked.parse(answer)
  306. // if(!getCookieObject().preQuesAns){
  307. // window.document.cookie=`preQuesAns=""`
  308. // }
  309. // let preQuesAns = getCookieObject().preQuesAns+answer
  310. // window.document.cookie=`preQuesAns=${your_qus}${preQuesAns}`
  311. // sendModerations()
  312. }catch(err){
  313. console.log(`err:${err}`)
  314. }
  315. }
  316. // const answer = JSON.parse(data.response.split("\n\n").slice(-3, -2)[0].slice(6)).message.content.parts[0]
  317. }
  318. },*/
  319. onprogress:function(msg){
  320. //console.log(msg) //Todo
  321. },
  322. onerror: function (err) {
  323. document.getElementById('gptAnswer').innerHTML=`<div>some err happends,errinfo :<br>${err}</div>`
  324. },
  325. ontimeout: function (err) {
  326. document.getElementById('gptAnswer').innerHTML=`<div>Opps!TimeOut,Please try again,errinfo:<br>${err}</div>`
  327. }
  328. })
  329. }
  330. }
  331. function creatBox(){
  332. return new Promise((resolve)=>{
  333. var divE = document.createElement('div');
  334. var divId = document.createAttribute("id"); //创建属性
  335. divId.value = 'gptDiv'; //设置属性值
  336. divE.setAttributeNode(divId); //给div添加属性
  337. var pE = document.createElement('p');
  338. var pClass= document.createAttribute('class');
  339. pClass.value = 'textClass';
  340. pE.setAttributeNode(pClass)
  341. var pText = document.createTextNode("chatGPT tools Plus ++ v0.0.1已启动");
  342. pE.appendChild(pText);
  343. divE.appendChild(pE);
  344. divE.innerHTML=`
  345. <div id="gptInputBox">
  346. <input id="gptInput" type=text><button id="button_GPT" >chat一下</button>
  347. </div>
  348. <div id=gptCueBox>
  349. <p id="gptStatus">&nbsp openAI 已就绪,请输入你的问题</p>
  350. <article id="gptAnswer" class="markdown-body"><div id="gptAnswer_inner">chatGPT tools Plus ++ v1.3.1已启动<div></article>
  351. </div><p></p>`
  352. resolve(divE)
  353. })
  354. }
  355. async function pivElemAddEventAndValue(append_case){
  356. var search_content
  357.  
  358. if(append_case===2){
  359. search_content=document.getElementById('kw').value
  360. }
  361. if(append_case===1){
  362. search_content=document.querySelector("#tsf > div:nth-child(1) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input:nth-child(3)").value
  363. }
  364. if(append_case===0){
  365. search_content=document.getElementsByClassName('b_searchbox')[0].value
  366. }
  367. document.getElementById("gptInput").value=search_content
  368. document.getElementById('button_GPT').addEventListener('click',()=>{
  369. your_qus=document.getElementById("gptInput").value
  370. do_it()
  371.  
  372. })
  373.  
  374.  
  375. }
  376. async function appendBox(append_case){
  377. return new Promise((resolve,reject)=>{
  378. creatBox().then((divE)=>{
  379. switch (append_case){
  380. case 0: //bing
  381. if(divE){
  382. document.getElementById('b_context').prepend(divE)
  383. }
  384. break;
  385. case 1://google
  386. if(document.getElementsByClassName('TQc1id ')[0]){
  387. document.getElementsByClassName('TQc1id ')[0].prepend(divE);
  388. }
  389. else{
  390. document.getElementById("rcnt").appendChild(divE);
  391. }
  392. break;
  393. case 2:
  394. if(document.getElementById('content_right')){
  395. document.getElementById('content_right').prepend(divE)
  396. }
  397. break;
  398. default :
  399. if(divE){
  400. console.log(`啥情况${divE}`)
  401. }
  402. }}).catch((err)=>{
  403. throw new Error(err)
  404. })
  405.  
  406. resolve("finished")
  407. })
  408. }
  409. //焦点函数
  410. function isBlur(){
  411. var myInput = document.getElementById('gptInput');
  412. if (myInput == document.activeElement) {
  413. return 1
  414. } else {
  415. return 0
  416. }
  417. }
  418. function keyEvent(){
  419. document.onkeydown = function (e) {
  420. var keyNum = window.event ? e.keyCode : e.which;
  421. if (13 == keyNum) {
  422. if (isBlur()) {
  423. document.getElementById('button_GPT').click()
  424. }
  425. else{
  426. console.log("失焦不执行")
  427. }
  428.  
  429. }}
  430.  
  431. }
  432. function checkIp(){
  433. GM_xmlhttpRequest({
  434. method: "GET",
  435. url: "http://ip-api.com/json/",
  436. onloadend: function (data) {
  437. if(data){
  438. try{
  439. data=JSON.parse(data.response)
  440. }catch(err){
  441. console.log(err)
  442. }
  443. console.log(data.country)
  444. if(data.country=="Hong Kong"){
  445. document.getElementById('gptStatus').innerHTML=`&nbsp openAI 已就绪,请输入你的问题`
  446. }
  447. }
  448. else{
  449. document.getElementById('gptStatus').innerHTML=`&nbsp openAI 没有就绪,请更换你的IP为非大陆节点`
  450. throw new Error('Error while executing the code');
  451. }
  452. },
  453. onerror: function (err) {
  454. document.getElementById('gptStatus').innerHTML=`&nbsp openAI 没有就绪,请更换你的IP为非大陆节点`
  455. throw new Error('Error while executing the code');
  456. },
  457. ontimeout: function (err) {
  458. document.getElementById('gptStatus').innerHTML=`&nbsp openAI 没有就绪,请更换你的IP为非大陆节点`
  459. throw new Error('Error while executing the code');
  460. }
  461. })
  462. }
  463. function addBothStyle(){
  464. GM_addStyle(`
  465. #dot{
  466. height: 4px;
  467. width: 4px;
  468. display: inline-block;
  469. border-radius: 2px;
  470. animation: dotting 2.4s infinite step-start;
  471. }
  472. @keyframes dotting {
  473. 25%{
  474. box-shadow: 4px 0 0 #71777D;
  475. }
  476. 50%{
  477. box-shadow: 4px 0 0 #71777D ,14px 0 0 #71777D;
  478. }
  479. 75%{
  480. box-shadow: 4px 0 0 #71777D ,14px 0 0 #71777D, 24px 0 0 #71777D;
  481. }
  482. }
  483. pre{
  484. overflow-x: scroll;
  485. overflow-y: hidden;
  486. background: #fffaec;
  487. border-radius: 4px;
  488. padding: 14px 3px;
  489. }
  490. pre::-webkit-scrollbar {
  491. }
  492. `)
  493. }
  494. function getYourCookie(){
  495. GM_xmlhttpRequest({
  496. method: "GET",
  497. url: "https://chat.openai.com/api/auth/session",
  498. onloadend: function (data) {
  499. if(data){
  500. data=JSON.parse(data.response)
  501. console.log(data.accessToken)
  502. // window.document.cookie=`your_cookie=${data.accessToken};expire:1000*60*60*24`
  503. setCookie("your_cookie",data.accessToken,1)
  504. }
  505. },
  506. onerror: function (err) {
  507. throw new Error('Error while executing the code');
  508.  
  509. },
  510. ontimeout: function (err) {
  511. throw new Error('Error while executing the code');
  512. }
  513. })
  514.  
  515.  
  516. }
  517. function setCookie(cname,cvalue,exdays)
  518. {
  519. var d = new Date();
  520. d.setTime(d.getTime()+(exdays*24*60*60*1000));
  521. var expires = "expires="+d.toGMTString();
  522. document.cookie = cname + "=" + cvalue + "; " + expires;
  523. }
  524. //原生cookie函数
  525. function getCookieObject() {
  526. let cookieString = document.cookie;
  527. cookieString = cookieString.substring(0, cookieString.length - 1);
  528. let tempCookieArray = cookieString.split('; ');
  529.  
  530. let cookieObject = {}; // 存放 cookie 键值对
  531.  
  532. tempCookieArray.forEach(item => {
  533. let name = item.substring(0, item.indexOf('='));
  534. let value = item.substring(item.indexOf('=') + 1);
  535. value = decodeURIComponent(value); // 还原字符串
  536. cookieObject[name] = value; // 将键值插入中这个对象中
  537. });
  538.  
  539. return cookieObject // 返回包含 cookie 键值对的对象
  540. }
  541. function sendModerations(){
  542. GM_xmlhttpRequest({
  543. method: "POST",
  544. url: requestUrl,
  545. headers: {
  546. "Content-Type": "application/json",
  547. Authorization: `Bearer ${your_cookie}`,
  548. },
  549. data:JSON.stringify({
  550. input:getCookieObject().preQuesAns,
  551. model:"text-moderation-playground"
  552. }),
  553. onloadend: function (data) {
  554. console.log(data)
  555. },
  556. onerror: function (err) {
  557. throw new Error('Error while executing the code');
  558.  
  559. },
  560. ontimeout: function (err) {
  561. throw new Error('Error while executing the code');
  562. }
  563. })
  564.  
  565.  
  566. }
  567. function autoClick(){
  568. document.getElementById('button_GPT').click()
  569. }
  570. function linkToBing_beautification_script(){
  571.  
  572. if(getCookieObject.blurDeg && getCookieObject.aDeg1 && getCookieObject.aDeg2){
  573. document.getElementById('gptDiv').style.background=`#ffffff${getCookieObject.aDeg2}`
  574. document.getElementById('gptDiv').style.backdropFilter=`${getCookieObject.blurDeg}`
  575. }
  576. }
  577. function creatBox_and_addEventlis(append_case){
  578. var divE = document.createElement('div');
  579. var divId = document.createAttribute("id"); //创建属性
  580. divId.value = 'gptDiv'; //设置属性值
  581. divE.setAttributeNode(divId); //给div添加属性
  582. var pE = document.createElement('p');
  583. var pClass= document.createAttribute('class');
  584. pClass.value = 'textClass';
  585. pE.setAttributeNode(pClass)
  586. var pText = document.createTextNode("chatGPT tools Plus ++ v0.1.3已启动");
  587. pE.appendChild(pText);
  588. divE.appendChild(pE);
  589. switch (append_case){
  590. case 0:
  591. if(divE){
  592. document.getElementById('b_context').prepend(divE)
  593. }
  594. break;
  595. case 1:
  596. if(document.getElementsByClassName('TQc1id ')[0]){
  597. document.getElementsByClassName('TQc1id ')[0].prepend(divE);
  598. }
  599. else{
  600. document.getElementById("rcnt").appendChild(divE);
  601. }
  602. break;
  603. case 2:
  604. if(document.getElementById('content_right')){
  605. document.getElementById('content_right').prepend(divE)
  606. }
  607. break;
  608. default :
  609. if(divE){
  610. document.getElementById('b_context').prepend(divE)
  611. }
  612. }
  613. 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++免费版v0.1.3已启动</div></div><p></p>`
  614. var search_content
  615. if(append_case===2){
  616. search_content=document.getElementById('kw').value
  617. }
  618. if(append_case===1){
  619. search_content=document.querySelector("#tsf > div:nth-child(1) > div.A8SBwf > div.RNNXgb > div > div.a4bIc > input:nth-child(3)").value
  620. }
  621. if(append_case===0){
  622. search_content=document.getElementsByClassName('b_searchbox')[0].value
  623. }
  624. document.getElementById("gptInput").value=search_content
  625. document.getElementById('button_GPT').addEventListener('click',()=>{
  626. your_qus=document.getElementById("gptInput").value
  627. do_it()
  628.  
  629. })
  630. }
  631. function log(a){
  632. console.log(a)
  633. }
  634.  
  635. function Uint8ArrayToString(fileData){
  636. var dataString = "";
  637. for (var i = 0; i < fileData.length; i++) {
  638. dataString += String.fromCharCode(fileData[i]);
  639. }
  640.  
  641. return dataString
  642. }
  643. function decodeUnicode(str) {
  644. str = str.replace(/\\/g, "%");
  645. //转换中文
  646. str = unescape(str);
  647. //将其他受影响的转换回原来
  648. str = str.replace(/%/g, "\\");
  649. //对网址的链接进行处理
  650. str = str.replace(/\\/g, "");
  651. return str;
  652. }
  653. function mdConverter(rawData) {
  654. var converter = new showdown.Converter(); //增加拓展table
  655. converter.setOption('tables', true); //启用表格选项。从showdown 1.2.0版开始,表支持已作为可选功能移入核心拓展,showdown.table.min.js扩展已被弃用
  656. var view = converter.makeHtml(rawData);
  657. return view;
  658. }
  659.  
  660.  
  661.  
  662. })();