ChatGPT Search


SUBMITTED BY: ccont2246

DATE: Dec. 22, 2022, 12:41 p.m.

FORMAT: Text only

SIZE: 25.0 kB

HITS: 8764

  1. // ==UserScript==
  2. // @name ChatGPT Search
  3. // @name:zh-CN ChatGPT 搜索
  4. // @name:zh-TW ChatGPT 搜索
  5. // @namespace https://greasyfork.org/scripts/456077
  6. // @version 0.7.1
  7. // @author Zheng Bang-Bo(https://github.com/zhengbangbo)
  8. // @description ChatGPT answers displayed in sidebar after search (Google, Bing, Baidu, DuckDuckGo and DeepL)
  9. // @description:zh-CN 搜索后侧栏显示 ChatGPT 回答(Google、Bing、百度、DuckDuckGo和DeepL)
  10. // @description:zh-TW 搜索後側欄顯示 ChatGPT 回答(Google、Bing、百度、DuckDuckGo和DeepL)
  11. // @license MIT
  12. // @icon https://github.com/zhengbangbo/oss/raw/main/logo/chat-gpt-userscript.png
  13. // @match https://*.google.com/search*
  14. // @match https://*.google.ad/search*
  15. // @match https://*.google.ae/search*
  16. // @match https://*.google.com.af/search*
  17. // @match https://*.google.com.ag/search*
  18. // @match https://*.google.com.ai/search*
  19. // @match https://*.google.al/search*
  20. // @match https://*.google.am/search*
  21. // @match https://*.google.co.ao/search*
  22. // @match https://*.google.com.ar/search*
  23. // @match https://*.google.as/search*
  24. // @match https://*.google.at/search*
  25. // @match https://*.google.com.au/search*
  26. // @match https://*.google.az/search*
  27. // @match https://*.google.ba/search*
  28. // @match https://*.google.com.bd/search*
  29. // @match https://*.google.be/search*
  30. // @match https://*.google.bf/search*
  31. // @match https://*.google.bg/search*
  32. // @match https://*.google.com.bh/search*
  33. // @match https://*.google.bi/search*
  34. // @match https://*.google.bj/search*
  35. // @match https://*.google.com.bn/search*
  36. // @match https://*.google.com.bo/search*
  37. // @match https://*.google.com.br/search*
  38. // @match https://*.google.bs/search*
  39. // @match https://*.google.bt/search*
  40. // @match https://*.google.co.bw/search*
  41. // @match https://*.google.by/search*
  42. // @match https://*.google.com.bz/search*
  43. // @match https://*.google.ca/search*
  44. // @match https://*.google.cd/search*
  45. // @match https://*.google.cf/search*
  46. // @match https://*.google.cg/search*
  47. // @match https://*.google.ch/search*
  48. // @match https://*.google.ci/search*
  49. // @match https://*.google.co.ck/search*
  50. // @match https://*.google.cl/search*
  51. // @match https://*.google.cm/search*
  52. // @match https://*.google.cn/search*
  53. // @match https://*.google.com.co/search*
  54. // @match https://*.google.co.cr/search*
  55. // @match https://*.google.com.cu/search*
  56. // @match https://*.google.cv/search*
  57. // @match https://*.google.com.cy/search*
  58. // @match https://*.google.cz/search*
  59. // @match https://*.google.de/search*
  60. // @match https://*.google.dj/search*
  61. // @match https://*.google.dk/search*
  62. // @match https://*.google.dm/search*
  63. // @match https://*.google.com.do/search*
  64. // @match https://*.google.dz/search*
  65. // @match https://*.google.com.ec/search*
  66. // @match https://*.google.ee/search*
  67. // @match https://*.google.com.eg/search*
  68. // @match https://*.google.es/search*
  69. // @match https://*.google.com.et/search*
  70. // @match https://*.google.fi/search*
  71. // @match https://*.google.com.fj/search*
  72. // @match https://*.google.fm/search*
  73. // @match https://*.google.fr/search*
  74. // @match https://*.google.ga/search*
  75. // @match https://*.google.ge/search*
  76. // @match https://*.google.gg/search*
  77. // @match https://*.google.com.gh/search*
  78. // @match https://*.google.com.gi/search*
  79. // @match https://*.google.gl/search*
  80. // @match https://*.google.gm/search*
  81. // @match https://*.google.gr/search*
  82. // @match https://*.google.com.gt/search*
  83. // @match https://*.google.gy/search*
  84. // @match https://*.google.com.hk/search*
  85. // @match https://*.google.hn/search*
  86. // @match https://*.google.hr/search*
  87. // @match https://*.google.ht/search*
  88. // @match https://*.google.hu/search*
  89. // @match https://*.google.co.id/search*
  90. // @match https://*.google.ie/search*
  91. // @match https://*.google.co.il/search*
  92. // @match https://*.google.im/search*
  93. // @match https://*.google.co.in/search*
  94. // @match https://*.google.iq/search*
  95. // @match https://*.google.is/search*
  96. // @match https://*.google.it/search*
  97. // @match https://*.google.je/search*
  98. // @match https://*.google.com.jm/search*
  99. // @match https://*.google.jo/search*
  100. // @match https://*.google.co.jp/search*
  101. // @match https://*.google.co.ke/search*
  102. // @match https://*.google.com.kh/search*
  103. // @match https://*.google.ki/search*
  104. // @match https://*.google.kg/search*
  105. // @match https://*.google.co.kr/search*
  106. // @match https://*.google.com.kw/search*
  107. // @match https://*.google.kz/search*
  108. // @match https://*.google.la/search*
  109. // @match https://*.google.com.lb/search*
  110. // @match https://*.google.li/search*
  111. // @match https://*.google.lk/search*
  112. // @match https://*.google.co.ls/search*
  113. // @match https://*.google.lt/search*
  114. // @match https://*.google.lu/search*
  115. // @match https://*.google.lv/search*
  116. // @match https://*.google.com.ly/search*
  117. // @match https://*.google.co.ma/search*
  118. // @match https://*.google.md/search*
  119. // @match https://*.google.me/search*
  120. // @match https://*.google.mg/search*
  121. // @match https://*.google.mk/search*
  122. // @match https://*.google.ml/search*
  123. // @match https://*.google.com.mm/search*
  124. // @match https://*.google.mn/search*
  125. // @match https://*.google.ms/search*
  126. // @match https://*.google.com.mt/search*
  127. // @match https://*.google.mu/search*
  128. // @match https://*.google.mv/search*
  129. // @match https://*.google.mw/search*
  130. // @match https://*.google.com.mx/search*
  131. // @match https://*.google.com.my/search*
  132. // @match https://*.google.co.mz/search*
  133. // @match https://*.google.com.na/search*
  134. // @match https://*.google.com.ng/search*
  135. // @match https://*.google.com.ni/search*
  136. // @match https://*.google.ne/search*
  137. // @match https://*.google.nl/search*
  138. // @match https://*.google.no/search*
  139. // @match https://*.google.com.np/search*
  140. // @match https://*.google.nr/search*
  141. // @match https://*.google.nu/search*
  142. // @match https://*.google.co.nz/search*
  143. // @match https://*.google.com.om/search*
  144. // @match https://*.google.com.pa/search*
  145. // @match https://*.google.com.pe/search*
  146. // @match https://*.google.com.pg/search*
  147. // @match https://*.google.com.ph/search*
  148. // @match https://*.google.com.pk/search*
  149. // @match https://*.google.pl/search*
  150. // @match https://*.google.pn/search*
  151. // @match https://*.google.com.pr/search*
  152. // @match https://*.google.ps/search*
  153. // @match https://*.google.pt/search*
  154. // @match https://*.google.com.py/search*
  155. // @match https://*.google.com.qa/search*
  156. // @match https://*.google.ro/search*
  157. // @match https://*.google.ru/search*
  158. // @match https://*.google.rw/search*
  159. // @match https://*.google.com.sa/search*
  160. // @match https://*.google.com.sb/search*
  161. // @match https://*.google.sc/search*
  162. // @match https://*.google.se/search*
  163. // @match https://*.google.com.sg/search*
  164. // @match https://*.google.sh/search*
  165. // @match https://*.google.si/search*
  166. // @match https://*.google.sk/search*
  167. // @match https://*.google.com.sl/search*
  168. // @match https://*.google.sn/search*
  169. // @match https://*.google.so/search*
  170. // @match https://*.google.sm/search*
  171. // @match https://*.google.sr/search*
  172. // @match https://*.google.st/search*
  173. // @match https://*.google.com.sv/search*
  174. // @match https://*.google.td/search*
  175. // @match https://*.google.tg/search*
  176. // @match https://*.google.co.th/search*
  177. // @match https://*.google.com.tj/search*
  178. // @match https://*.google.tl/search*
  179. // @match https://*.google.tm/search*
  180. // @match https://*.google.tn/search*
  181. // @match https://*.google.to/search*
  182. // @match https://*.google.com.tr/search*
  183. // @match https://*.google.tt/search*
  184. // @match https://*.google.com.tw/search*
  185. // @match https://*.google.co.tz/search*
  186. // @match https://*.google.com.ua/search*
  187. // @match https://*.google.co.ug/search*
  188. // @match https://*.google.co.uk/search*
  189. // @match https://*.google.com.uy/search*
  190. // @match https://*.google.co.uz/search*
  191. // @match https://*.google.com.vc/search*
  192. // @match https://*.google.co.ve/search*
  193. // @match https://*.google.vg/search*
  194. // @match https://*.google.co.vi/search*
  195. // @match https://*.google.com.vn/search*
  196. // @match https://*.google.vu/search*
  197. // @match https://*.google.ws/search*
  198. // @match https://*.google.rs/search*
  199. // @match https://*.google.co.za/search*
  200. // @match https://*.google.co.zm/search*
  201. // @match https://*.google.co.zw/search*
  202. // @match https://*.google.cat/search*
  203. // @match https://www.bing.com/search*
  204. // @match https://cn.bing.com/search*
  205. // @match https://www.baidu.com/s*
  206. // @match https://duckduckgo.com/*
  207. // @match https://www.deepl.com/translator*
  208. // @connect chat.openai.com
  209. // @grant GM_addStyle
  210. // @grant GM_deleteValue
  211. // @grant GM_getValue
  212. // @grant GM_info
  213. // @grant GM_registerMenuCommand
  214. // @grant GM_setValue
  215. // @grant GM_unregisterMenuCommand
  216. // @grant GM_xmlhttpRequest
  217. // ==/UserScript==
  218. (e=>{const t=document.createElement("style");t.dataset.source="vite-plugin-monkey",t.innerText=e,document.head.appendChild(t)})(".chat-gpt-container{max-width:369px;margin-bottom:30px;border-radius:8px;border:1px solid #dadce0;padding:15px;flex-basis:0;flex-grow:1;word-wrap:break-word;white-space:pre-wrap}.chat-gpt-container p{margin:0}.chat-gpt-container .prefix{font-weight:700}.chat-gpt-container .loading{color:#b6b8ba;animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes pulse{0%,to{opacity:1}50%{opacity:.5}}.chat-gpt-container.sidebar-free{margin-left:60px;height:fit-content}.chat-gpt-container pre{white-space:pre-wrap;min-width:0;margin-bottom:0;line-height:20px}.chat-gpt-translate-button{border-radius:8px;border:1px solid #dadce0;padding:5px}.chat-gpt-translate-button:hover{color:#006494;transition:color .1s ease-out}.chat-gpt-translate-button[disabled]{color:#eee}");
  219. (function() {
  220. "use strict";
  221. var monkeyWindow = window;
  222. var GM_info = /* @__PURE__ */ (() => monkeyWindow.GM_info)();
  223. var GM_setValue = /* @__PURE__ */ (() => monkeyWindow.GM_setValue)();
  224. var GM_deleteValue = /* @__PURE__ */ (() => monkeyWindow.GM_deleteValue)();
  225. var GM_addStyle = /* @__PURE__ */ (() => monkeyWindow.GM_addStyle)();
  226. var GM_registerMenuCommand = /* @__PURE__ */ (() => monkeyWindow.GM_registerMenuCommand)();
  227. var GM_unregisterMenuCommand = /* @__PURE__ */ (() => monkeyWindow.GM_unregisterMenuCommand)();
  228. var GM_xmlhttpRequest = /* @__PURE__ */ (() => monkeyWindow.GM_xmlhttpRequest)();
  229. var GM_getValue = /* @__PURE__ */ (() => monkeyWindow.GM_getValue)();
  230. function isBlockedbyCloudflare(resp) {
  231. try {
  232. const html = new DOMParser().parseFromString(resp, "text/html");
  233. const title = html.querySelector("title");
  234. return title.innerText === "Just a moment...";
  235. } catch (error) {
  236. return false;
  237. }
  238. }
  239. const container = document.createElement("div");
  240. function getContainer() {
  241. return container;
  242. }
  243. function initContainer() {
  244. const container2 = getContainer();
  245. container2.className = "chat-gpt-container";
  246. container2.innerHTML = '<p class="loading">Waiting for ChatGPT response...</p>';
  247. }
  248. function containerShow(answer) {
  249. const container2 = getContainer();
  250. container2.innerHTML = '<p><span class="prefix">Chat GPT</span><pre></pre></p>';
  251. container2.querySelector("pre").textContent = answer;
  252. }
  253. function containerAlert(htmlStr) {
  254. const container2 = getContainer();
  255. container2.innerHTML = htmlStr;
  256. }
  257. function alertLogin() {
  258. containerAlert('<p>Please login at <a href="https://chat.openai.com" target="_blank" rel="noreferrer">chat.openai.com</a> first</p>');
  259. }
  260. function alertFrequentRequests() {
  261. containerAlert("<p>Too many requests in 1 hour. Try again later.</p>");
  262. }
  263. function removeAccessToken() {
  264. GM_deleteValue("accessToken");
  265. }
  266. function getAccessToken() {
  267. return new Promise((resolve, rejcet) => {
  268. let accessToken = GM_getValue("accessToken");
  269. if (!accessToken) {
  270. GM_xmlhttpRequest({
  271. url: "https://chat.openai.com/api/auth/session",
  272. onload: function(response) {
  273. if (isBlockedbyCloudflare(response.responseText)) {
  274. alertLogin();
  275. return;
  276. }
  277. const accessToken2 = JSON.parse(response.responseText).accessToken;
  278. if (!accessToken2) {
  279. rejcet("UNAUTHORIZED");
  280. }
  281. GM_setValue("accessToken", accessToken2);
  282. resolve(accessToken2);
  283. },
  284. onerror: function(error) {
  285. rejcet(error);
  286. },
  287. ontimeout: () => {
  288. console.log("getAccessToken timeout!");
  289. }
  290. });
  291. } else {
  292. resolve(accessToken);
  293. }
  294. });
  295. }
  296. function getUserscriptManager() {
  297. try {
  298. const userscriptManager = GM_info.scriptHandler;
  299. return userscriptManager;
  300. } catch (error) {
  301. return "other";
  302. }
  303. }
  304. function uuidv4() {
  305. var s = [];
  306. var hexDigits = "0123456789abcdef";
  307. for (var i = 0; i < 36; i++) {
  308. s[i] = hexDigits.substr(Math.floor(Math.random() * 16), 1);
  309. }
  310. s[14] = "4";
  311. s[19] = hexDigits.substr(s[19] & 3 | 8, 1);
  312. s[8] = s[13] = s[18] = s[23] = "-";
  313. var uuid = s.join("");
  314. return uuid;
  315. }
  316. async function getAnswer(question, callback) {
  317. function responseType() {
  318. if (getUserscriptManager() === "Tampermonkey") {
  319. return "stream";
  320. } else {
  321. return "text";
  322. }
  323. }
  324. function onload() {
  325. function finish() {
  326. if (typeof callback === "function") {
  327. return callback("finish");
  328. }
  329. }
  330. finish();
  331. return function(event) {
  332. console.log(event.status);
  333. if (event.status === 401) {
  334. removeAccessToken();
  335. alertLogin();
  336. }
  337. if (event.status === 403) {
  338. alertLogin();
  339. }
  340. if (event.status === 429) {
  341. alertFrequentRequests();
  342. }
  343. if (getUserscriptManager() !== "Tampermonkey") {
  344. if (event.response) {
  345. const answer = JSON.parse(event.response.split("\n\n").slice(-3, -2)[0].slice(6)).message.content.parts[0];
  346. containerShow(answer);
  347. }
  348. }
  349. };
  350. }
  351. function onloadstart() {
  352. if (getUserscriptManager() === "Tampermonkey") {
  353. return function(stream) {
  354. const reader = stream.response.getReader();
  355. reader.read().then(function processText({ done, value }) {
  356. if (done) {
  357. return;
  358. }
  359. let responseItem = String.fromCharCode(...Array.from(value));
  360. const items = responseItem.split("\n\n");
  361. if (items.length > 2) {
  362. const lastItem = items.slice(-3, -2)[0];
  363. if (lastItem.startsWith("data: [DONE]")) {
  364. responseItem = items.slice(-4, -3)[0];
  365. } else {
  366. responseItem = lastItem;
  367. }
  368. }
  369. if (responseItem.startsWith("data: {")) {
  370. const answer = JSON.parse(responseItem.slice(6)).message.content.parts[0];
  371. containerShow(answer);
  372. } else if (responseItem.startsWith("data: [DONE]")) {
  373. return;
  374. }
  375. return reader.read().then(processText);
  376. });
  377. };
  378. }
  379. }
  380. try {
  381. const accessToken = await getAccessToken();
  382. GM_xmlhttpRequest({
  383. method: "POST",
  384. url: "https://chat.openai.com/backend-api/conversation",
  385. headers: {
  386. "Content-Type": " application/json",
  387. Authorization: `Bearer ${accessToken}`
  388. },
  389. responseType: responseType(),
  390. data: JSON.stringify({
  391. action: "next",
  392. messages: [
  393. {
  394. id: uuidv4(),
  395. role: "user",
  396. content: {
  397. content_type: "text",
  398. parts: [question]
  399. }
  400. }
  401. ],
  402. model: "text-davinci-002-render",
  403. parent_message_id: uuidv4()
  404. }),
  405. onloadstart: onloadstart(),
  406. onload: onload(),
  407. onerror: function(event) {
  408. console.error("getAnswer error: ", event);
  409. },
  410. ontimeout: function(event) {
  411. console.error("getAnswer timeout: ", event);
  412. }
  413. });
  414. } catch (error) {
  415. if (error === "UNAUTHORIZED") {
  416. removeAccessToken();
  417. alertLogin();
  418. }
  419. console.error("getAnswer error: ", error);
  420. }
  421. }
  422. const _default = "";
  423. function getWebsite() {
  424. function configRequestImmediately(name) {
  425. return {
  426. name,
  427. type: "immediately"
  428. };
  429. }
  430. function configRequestAfterClickButton(name) {
  431. return {
  432. name,
  433. type: "after-click-button"
  434. };
  435. }
  436. if (location.hostname.indexOf(".google.") !== -1) {
  437. return configRequestImmediately("google");
  438. }
  439. switch (location.hostname) {
  440. case "www.bing.com":
  441. case "cn.bing.com":
  442. return configRequestImmediately("bing");
  443. case "www.baidu.com":
  444. return configRequestImmediately("baidu");
  445. case "duckduckgo.com":
  446. return configRequestImmediately("duckduckgo");
  447. case "www.deepl.com":
  448. return configRequestAfterClickButton("deepl");
  449. default:
  450. return "unknow";
  451. }
  452. }
  453. function getQuestion() {
  454. switch (getWebsite().name) {
  455. case "baidu":
  456. return new URL(window.location.href).searchParams.get("wd");
  457. default:
  458. return new URL(window.location.href).searchParams.get("q");
  459. }
  460. }
  461. function getPosition() {
  462. return GM_getValue("containerPosition", 1);
  463. }
  464. function setPosition(newPosition) {
  465. GM_setValue("containerPosition", newPosition);
  466. }
  467. function initUI() {
  468. function googleInjectContainer() {
  469. if (getPosition() === 1) {
  470. const container2 = getContainer();
  471. const siderbarContainer = document.getElementById("rhs");
  472. if (siderbarContainer) {
  473. siderbarContainer.prepend(container2);
  474. } else {
  475. container2.classList.add("sidebar-free");
  476. document.getElementById("rcnt").appendChild(container2);
  477. }
  478. } else {
  479. GM_addStyle(".chat-gpt-container{max-width: 100%!important}");
  480. const container2 = getContainer();
  481. const mainContainer = document.querySelector("#search");
  482. if (mainContainer) {
  483. mainContainer.prepend(container2);
  484. }
  485. }
  486. }
  487. function bingInjectContainer() {
  488. if (getPosition() === 1) {
  489. const container2 = getContainer();
  490. const siderbarContainer = document.getElementById("b_context");
  491. siderbarContainer.prepend(container2);
  492. } else {
  493. GM_addStyle(".chat-gpt-container{max-width: 100%!important}");
  494. GM_addStyle(".chat-gpt-container{width: 70vw}");
  495. const container2 = getContainer();
  496. const mainBarContainer = document.querySelector("main");
  497. mainBarContainer.prepend(container2);
  498. }
  499. }
  500. function baiduInjectContainer() {
  501. if (getPosition() === 1) {
  502. const container2 = getContainer();
  503. const siderbarContainer = document.getElementById("content_right");
  504. siderbarContainer.prepend(container2);
  505. } else {
  506. GM_addStyle(".chat-gpt-container{max-width: 100%!important}");
  507. const container2 = getContainer();
  508. const siderbarContainer = document.querySelector("#content_left");
  509. siderbarContainer.prepend(container2);
  510. }
  511. }
  512. function duckduckgoInjectContainer() {
  513. const container2 = getContainer();
  514. const siderbarContainer = document.getElementsByClassName("results--sidebar")[0];
  515. siderbarContainer.prepend(container2);
  516. }
  517. function deeplInjectContainer() {
  518. const container2 = getContainer();
  519. container2.style.maxWidth = "1000px";
  520. const button = document.createElement("button");
  521. button.innerHTML = "Chat GPT Translate";
  522. button.className = "chat-gpt-translate-button";
  523. document.getElementsByClassName("lmt__textarea_container")[0].appendChild(button);
  524. button.addEventListener("click", function() {
  525. initContainer();
  526. button.disabled = true;
  527. try {
  528. document.getElementsByClassName("lmt__raise_alternatives_placement")[0].insertBefore(container2, document.getElementsByClassName("lmt__translations_as_text")[0]);
  529. } catch {
  530. document.getElementsByClassName("lmt__textarea_container")[1].insertBefore(container2, document.getElementsByClassName("lmt__translations_as_text")[0]);
  531. }
  532. let outlang = document.querySelectorAll("strong[data-testid='deepl-ui-tooltip-target']")[0].innerHTML;
  533. let question = "Translate the following paragraph into " + outlang + " and only " + outlang + "\n\n" + document.getElementById("source-dummydiv").innerHTML;
  534. getAnswer(question, (t) => {
  535. console.log(t);
  536. button.disabled = false;
  537. });
  538. });
  539. }
  540. initContainer();
  541. switch (getWebsite().name) {
  542. case "google":
  543. googleInjectContainer();
  544. break;
  545. case "bing":
  546. bingInjectContainer();
  547. break;
  548. case "baidu":
  549. baiduInjectContainer();
  550. break;
  551. case "duckduckgo":
  552. duckduckgoInjectContainer();
  553. break;
  554. case "deepl":
  555. deeplInjectContainer();
  556. break;
  557. default:
  558. alertUnknowError();
  559. }
  560. }
  561. function initMenu() {
  562. let position_id = GM_registerMenuCommand("Container Position - Side(1)/Top(0): " + getPosition(), position_switch, "M");
  563. function position_switch() {
  564. GM_unregisterMenuCommand(position_id);
  565. setPosition((getPosition() + 1) % 2);
  566. position_id = GM_registerMenuCommand("Container Position - Side(1)/Top(0): " + getPosition(), position_switch, "M");
  567. location.reload();
  568. }
  569. }
  570. async function main() {
  571. initUI();
  572. initMenu();
  573. if (getWebsite().type === "immediately") {
  574. getAnswer(getQuestion());
  575. }
  576. }
  577. main().catch((e) => {
  578. console.log(e);
  579. });
  580. })();

comments powered by Disqus