ChatGPT Search

ChatGPT answers displayed in sidebar after search (Google, Bing, Baidu, DuckDuckGo and DeepL)

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name               ChatGPT Search
// @name:zh-CN         ChatGPT 搜索
// @name:zh-SG         ChatGPT 搜索
// @name:zh-TW         ChatGPT 搜索
// @name:zh-HK         ChatGPT 搜索
// @namespace          https://greasyfork.org/scripts/456077
// @version            0.8.0
// @author             Zheng Bang-Bo(https://github.com/zhengbangbo)
// @description        ChatGPT answers displayed in sidebar after search (Google, Bing, Baidu, DuckDuckGo and DeepL)
// @description:zh-CN  侧栏显示 ChatGPT 回答(Google、Bing、百度、DuckDuckGo和DeepL)
// @description:zh-SG  侧栏显示 ChatGPT 回答(Google、Bing、百度、DuckDuckGo和DeepL)
// @description:zh-TW  側欄顯示 ChatGPT 回答(Google、Bing、百度、DuckDuckGo和DeepL)
// @description:zh-HK  側欄顯示 ChatGPT 回答(Google、Bing、百度、DuckDuckGo和DeepL)
// @license            MIT
// @icon               https://github.com/zhengbangbo/oss/raw/main/logo/chat-gpt-userscript.png
// @match              https://*.google.com/search*
// @match              https://*.google.ad/search*
// @match              https://*.google.ae/search*
// @match              https://*.google.com.af/search*
// @match              https://*.google.com.ag/search*
// @match              https://*.google.com.ai/search*
// @match              https://*.google.al/search*
// @match              https://*.google.am/search*
// @match              https://*.google.co.ao/search*
// @match              https://*.google.com.ar/search*
// @match              https://*.google.as/search*
// @match              https://*.google.at/search*
// @match              https://*.google.com.au/search*
// @match              https://*.google.az/search*
// @match              https://*.google.ba/search*
// @match              https://*.google.com.bd/search*
// @match              https://*.google.be/search*
// @match              https://*.google.bf/search*
// @match              https://*.google.bg/search*
// @match              https://*.google.com.bh/search*
// @match              https://*.google.bi/search*
// @match              https://*.google.bj/search*
// @match              https://*.google.com.bn/search*
// @match              https://*.google.com.bo/search*
// @match              https://*.google.com.br/search*
// @match              https://*.google.bs/search*
// @match              https://*.google.bt/search*
// @match              https://*.google.co.bw/search*
// @match              https://*.google.by/search*
// @match              https://*.google.com.bz/search*
// @match              https://*.google.ca/search*
// @match              https://*.google.cd/search*
// @match              https://*.google.cf/search*
// @match              https://*.google.cg/search*
// @match              https://*.google.ch/search*
// @match              https://*.google.ci/search*
// @match              https://*.google.co.ck/search*
// @match              https://*.google.cl/search*
// @match              https://*.google.cm/search*
// @match              https://*.google.cn/search*
// @match              https://*.google.com.co/search*
// @match              https://*.google.co.cr/search*
// @match              https://*.google.com.cu/search*
// @match              https://*.google.cv/search*
// @match              https://*.google.com.cy/search*
// @match              https://*.google.cz/search*
// @match              https://*.google.de/search*
// @match              https://*.google.dj/search*
// @match              https://*.google.dk/search*
// @match              https://*.google.dm/search*
// @match              https://*.google.com.do/search*
// @match              https://*.google.dz/search*
// @match              https://*.google.com.ec/search*
// @match              https://*.google.ee/search*
// @match              https://*.google.com.eg/search*
// @match              https://*.google.es/search*
// @match              https://*.google.com.et/search*
// @match              https://*.google.fi/search*
// @match              https://*.google.com.fj/search*
// @match              https://*.google.fm/search*
// @match              https://*.google.fr/search*
// @match              https://*.google.ga/search*
// @match              https://*.google.ge/search*
// @match              https://*.google.gg/search*
// @match              https://*.google.com.gh/search*
// @match              https://*.google.com.gi/search*
// @match              https://*.google.gl/search*
// @match              https://*.google.gm/search*
// @match              https://*.google.gr/search*
// @match              https://*.google.com.gt/search*
// @match              https://*.google.gy/search*
// @match              https://*.google.com.hk/search*
// @match              https://*.google.hn/search*
// @match              https://*.google.hr/search*
// @match              https://*.google.ht/search*
// @match              https://*.google.hu/search*
// @match              https://*.google.co.id/search*
// @match              https://*.google.ie/search*
// @match              https://*.google.co.il/search*
// @match              https://*.google.im/search*
// @match              https://*.google.co.in/search*
// @match              https://*.google.iq/search*
// @match              https://*.google.is/search*
// @match              https://*.google.it/search*
// @match              https://*.google.je/search*
// @match              https://*.google.com.jm/search*
// @match              https://*.google.jo/search*
// @match              https://*.google.co.jp/search*
// @match              https://*.google.co.ke/search*
// @match              https://*.google.com.kh/search*
// @match              https://*.google.ki/search*
// @match              https://*.google.kg/search*
// @match              https://*.google.co.kr/search*
// @match              https://*.google.com.kw/search*
// @match              https://*.google.kz/search*
// @match              https://*.google.la/search*
// @match              https://*.google.com.lb/search*
// @match              https://*.google.li/search*
// @match              https://*.google.lk/search*
// @match              https://*.google.co.ls/search*
// @match              https://*.google.lt/search*
// @match              https://*.google.lu/search*
// @match              https://*.google.lv/search*
// @match              https://*.google.com.ly/search*
// @match              https://*.google.co.ma/search*
// @match              https://*.google.md/search*
// @match              https://*.google.me/search*
// @match              https://*.google.mg/search*
// @match              https://*.google.mk/search*
// @match              https://*.google.ml/search*
// @match              https://*.google.com.mm/search*
// @match              https://*.google.mn/search*
// @match              https://*.google.ms/search*
// @match              https://*.google.com.mt/search*
// @match              https://*.google.mu/search*
// @match              https://*.google.mv/search*
// @match              https://*.google.mw/search*
// @match              https://*.google.com.mx/search*
// @match              https://*.google.com.my/search*
// @match              https://*.google.co.mz/search*
// @match              https://*.google.com.na/search*
// @match              https://*.google.com.ng/search*
// @match              https://*.google.com.ni/search*
// @match              https://*.google.ne/search*
// @match              https://*.google.nl/search*
// @match              https://*.google.no/search*
// @match              https://*.google.com.np/search*
// @match              https://*.google.nr/search*
// @match              https://*.google.nu/search*
// @match              https://*.google.co.nz/search*
// @match              https://*.google.com.om/search*
// @match              https://*.google.com.pa/search*
// @match              https://*.google.com.pe/search*
// @match              https://*.google.com.pg/search*
// @match              https://*.google.com.ph/search*
// @match              https://*.google.com.pk/search*
// @match              https://*.google.pl/search*
// @match              https://*.google.pn/search*
// @match              https://*.google.com.pr/search*
// @match              https://*.google.ps/search*
// @match              https://*.google.pt/search*
// @match              https://*.google.com.py/search*
// @match              https://*.google.com.qa/search*
// @match              https://*.google.ro/search*
// @match              https://*.google.ru/search*
// @match              https://*.google.rw/search*
// @match              https://*.google.com.sa/search*
// @match              https://*.google.com.sb/search*
// @match              https://*.google.sc/search*
// @match              https://*.google.se/search*
// @match              https://*.google.com.sg/search*
// @match              https://*.google.sh/search*
// @match              https://*.google.si/search*
// @match              https://*.google.sk/search*
// @match              https://*.google.com.sl/search*
// @match              https://*.google.sn/search*
// @match              https://*.google.so/search*
// @match              https://*.google.sm/search*
// @match              https://*.google.sr/search*
// @match              https://*.google.st/search*
// @match              https://*.google.com.sv/search*
// @match              https://*.google.td/search*
// @match              https://*.google.tg/search*
// @match              https://*.google.co.th/search*
// @match              https://*.google.com.tj/search*
// @match              https://*.google.tl/search*
// @match              https://*.google.tm/search*
// @match              https://*.google.tn/search*
// @match              https://*.google.to/search*
// @match              https://*.google.com.tr/search*
// @match              https://*.google.tt/search*
// @match              https://*.google.com.tw/search*
// @match              https://*.google.co.tz/search*
// @match              https://*.google.com.ua/search*
// @match              https://*.google.co.ug/search*
// @match              https://*.google.co.uk/search*
// @match              https://*.google.com.uy/search*
// @match              https://*.google.co.uz/search*
// @match              https://*.google.com.vc/search*
// @match              https://*.google.co.ve/search*
// @match              https://*.google.vg/search*
// @match              https://*.google.co.vi/search*
// @match              https://*.google.com.vn/search*
// @match              https://*.google.vu/search*
// @match              https://*.google.ws/search*
// @match              https://*.google.rs/search*
// @match              https://*.google.co.za/search*
// @match              https://*.google.co.zm/search*
// @match              https://*.google.co.zw/search*
// @match              https://*.google.cat/search*
// @match              https://www.bing.com/search*
// @match              https://cn.bing.com/search*
// @match              https://www.baidu.com/s*
// @match              https://duckduckgo.com/*
// @match              https://www.deepl.com/translator*
// @connect            chat.openai.com
// @grant              GM_addStyle
// @grant              GM_deleteValue
// @grant              GM_getValue
// @grant              GM_info
// @grant              GM_registerMenuCommand
// @grant              GM_setValue
// @grant              GM_unregisterMenuCommand
// @grant              GM_xmlhttpRequest
// ==/UserScript==

(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}");

(function() {
  "use strict";
  var monkeyWindow = window;
  var GM_info = /* @__PURE__ */ (() => monkeyWindow.GM_info)();
  var GM_setValue = /* @__PURE__ */ (() => monkeyWindow.GM_setValue)();
  var GM_deleteValue = /* @__PURE__ */ (() => monkeyWindow.GM_deleteValue)();
  var GM_addStyle = /* @__PURE__ */ (() => monkeyWindow.GM_addStyle)();
  var GM_registerMenuCommand = /* @__PURE__ */ (() => monkeyWindow.GM_registerMenuCommand)();
  var GM_unregisterMenuCommand = /* @__PURE__ */ (() => monkeyWindow.GM_unregisterMenuCommand)();
  var GM_xmlhttpRequest = /* @__PURE__ */ (() => monkeyWindow.GM_xmlhttpRequest)();
  var GM_getValue = /* @__PURE__ */ (() => monkeyWindow.GM_getValue)();
  function getUserscriptManager() {
    try {
      const userscriptManager = GM_info.scriptHandler;
      return userscriptManager;
    } catch (error) {
      return "other";
    }
  }
  function uuidv4() {
    var s = [];
    var hexDigits = "0123456789abcdef";
    for (var i = 0; i < 36; i++) {
      s[i] = hexDigits.substr(Math.floor(Math.random() * 16), 1);
    }
    s[14] = "4";
    s[19] = hexDigits.substr(s[19] & 3 | 8, 1);
    s[8] = s[13] = s[18] = s[23] = "-";
    var uuid = s.join("");
    return uuid;
  }
  const lang = navigator.appName == "Netscape" ? navigator.language : navigator.userLanguage;
  let config = {};
  switch (lang) {
    case "zh-CN":
    case "zh-SG":
      config = {
        waitingResponse: "等待 ChatGPT 响应...",
        login: "请在以下地址登录:",
        tooManyRequests: "1小时内请求太多。请稍后再试。",
        checkClouflare: "请通过 Cloudflare 安全检查,地址为",
        unknowError: "哦,可能是个错误,请检查或提交到",
        networkException: "网络异常,请刷新页面。",
        containerPosition: "容器位置 - 侧面(1)/顶部(0): ",
        chatGPTTranslate: "ChatGPT 翻译"
      };
      break;
    case "zh-TW":
    case "zh-HK":
      config = {
        waitingResponse: "等待 ChatGPT 回應...",
        login: "請在以下地址登錄:",
        tooManyRequests: "1小時內請求太多。請稍後再試。",
        checkClouflare: "請通過 Cloudflare 安全檢查,地址為",
        unknowError: "哦,可能是個錯誤,請檢查或提交到",
        networkException: "網路異常,請刷新頁面。",
        containerPosition: "容器位置 - 側面(1)/頂部(0):",
        chatGPTTranslate: "ChatGPT 翻譯"
      };
      break;
    default:
      config = {
        waitingResponse: "Waiting for ChatGPT response...",
        login: "Please login at ",
        tooManyRequests: "Too many requests in 1 hour. Try again later.",
        checkClouflare: "Please pass Cloudflare security check at ",
        unknowError: "Oops, maybe it is a bug, please check or submit ",
        networkException: "Network exception, please refresh the page.",
        containerPosition: "Container Position - Side(1)/Top(0): ",
        chatGPTTranslate: "ChatGPT Translate"
      };
  }
  function i18n(name, param) {
    return config[name] ? config[name].replace("#t#", param) : name;
  }
  const container = document.createElement("div");
  function getContainer() {
    return container;
  }
  function initContainer() {
    const container2 = getContainer();
    container2.className = "chat-gpt-container";
    container2.innerHTML = `<p class="loading">${i18n("waitingResponse")}</p>`;
  }
  function containerShow(answer) {
    const container2 = getContainer();
    container2.innerHTML = '<p><span class="prefix">ChatGPT</span><pre></pre></p>';
    container2.querySelector("pre").textContent = answer;
  }
  function containerAlert(htmlStr) {
    const container2 = getContainer();
    container2.innerHTML = htmlStr;
  }
  function alertLogin() {
    containerAlert(`<p>${i18n("login")}<a href="https://chat.openai.com" target="_blank" rel="noreferrer">chat.openai.com</a></p>`);
  }
  function alertBlockedByCloudflare() {
    containerAlert(`<p>${i18n("checkClouflare")}<a href="https://chat.openai.com" target="_blank" rel="noreferrer">chat.openai.com</a></p>`);
  }
  function alertFrequentRequests() {
    containerAlert(`<p>${i18n("tooManyRequests")}</p>`);
  }
  function isBlockedbyCloudflare(resp) {
    try {
      const html = new DOMParser().parseFromString(resp, "text/html");
      const title = html.querySelector("title");
      return title.innerText === "Just a moment...";
    } catch (error) {
      return false;
    }
  }
  async function getAnswer(question, callback) {
    try {
      const accessToken = await getAccessToken();
      GM_xmlhttpRequest({
        method: "POST",
        url: "https://chat.openai.com/backend-api/conversation",
        headers: {
          "Content-Type": "	application/json",
          Authorization: `Bearer ${accessToken}`
        },
        responseType: responseType(),
        data: JSON.stringify({
          action: "next",
          messages: [
            {
              id: uuidv4(),
              role: "user",
              content: {
                content_type: "text",
                parts: [question]
              }
            }
          ],
          model: "text-davinci-002-render",
          parent_message_id: uuidv4()
        }),
        onloadstart: onloadstart(),
        onload: onload(),
        onerror: function(event) {
          console.error("getAnswer error: ", event);
        },
        ontimeout: function(event) {
          console.error("getAnswer timeout: ", event);
        }
      });
    } catch (error) {
      if (error === "UNAUTHORIZED") {
        removeAccessToken();
        alertLogin();
      }
      console.error("getAnswer error: ", error);
    }
    function responseType() {
      if (getUserscriptManager() === "Tampermonkey") {
        return "stream";
      } else {
        return "text";
      }
    }
    function onload() {
      function finish() {
        if (typeof callback === "function") {
          return callback("finish");
        }
      }
      finish();
      return function(event) {
        if (event.status === 401) {
          removeAccessToken();
          alertLogin();
        }
        if (event.status === 403) {
          alertBlockedByCloudflare();
        }
        if (event.status === 429) {
          alertFrequentRequests();
        }
        if (getUserscriptManager() !== "Tampermonkey") {
          if (event.response) {
            const answer = JSON.parse(event.response.split("\n\n").slice(-3, -2)[0].slice(6)).message.content.parts[0];
            containerShow(answer);
          }
        }
      };
    }
    function onloadstart() {
      if (getUserscriptManager() === "Tampermonkey") {
        return function(stream) {
          const reader = stream.response.getReader();
          reader.read().then(function processText({ done, value }) {
            if (done) {
              return;
            }
            let responseItem = String.fromCharCode(...Array.from(value));
            const items = responseItem.split("\n\n");
            if (items.length > 2) {
              const lastItem = items.slice(-3, -2)[0];
              if (lastItem.startsWith("data: [DONE]")) {
                responseItem = items.slice(-4, -3)[0];
              } else {
                responseItem = lastItem;
              }
            }
            if (responseItem.startsWith("data: {")) {
              const answer = JSON.parse(responseItem.slice(6)).message.content.parts[0];
              containerShow(answer);
            } else if (responseItem.startsWith("data: [DONE]")) {
              return;
            }
            return reader.read().then(processText);
          });
        };
      }
    }
  }
  function removeAccessToken() {
    GM_deleteValue("accessToken");
  }
  function getAccessToken() {
    return new Promise(async (resolve, rejcet) => {
      const accessToken = await GM_getValue("accessToken");
      if (!accessToken) {
        GM_xmlhttpRequest({
          url: "https://chat.openai.com/api/auth/session",
          onload: function(response) {
            if (isBlockedbyCloudflare(response.responseText)) {
              alertLogin();
              return;
            }
            const accessToken2 = JSON.parse(response.responseText).accessToken;
            if (!accessToken2) {
              rejcet("UNAUTHORIZED");
            }
            GM_setValue("accessToken", accessToken2);
            resolve(accessToken2);
          },
          onerror: function(error) {
            rejcet(error);
          },
          ontimeout: () => {
            console.error("getAccessToken timeout!");
          }
        });
      } else {
        resolve(accessToken);
      }
    });
  }
  const _default = "";
  function getWebsite() {
    if (location.hostname.indexOf(".google.") !== -1) {
      return configRequestImmediately("google");
    }
    switch (location.hostname) {
      case "www.bing.com":
      case "cn.bing.com":
        return configRequestImmediately("bing");
      case "www.baidu.com":
        return configRequestImmediately("baidu");
      case "duckduckgo.com":
        return configRequestImmediately("duckduckgo");
      case "www.deepl.com":
        return configRequestAfterClickButton("deepl");
      default:
        throw new Error(`unknow website: ${location.hostname}`);
    }
    function configRequestImmediately(name) {
      return {
        name,
        type: "immediately"
      };
    }
    function configRequestAfterClickButton(name) {
      return {
        name,
        type: "after-click-button"
      };
    }
  }
  function getQuestion() {
    switch (getWebsite().name) {
      case "baidu":
        return new URL(window.location.href).searchParams.get("wd");
      default:
        return new URL(window.location.href).searchParams.get("q");
    }
  }
  function getPosition() {
    return GM_getValue("containerPosition", 1);
  }
  function setPosition(newPosition) {
    GM_setValue("containerPosition", newPosition);
  }
  function initUI() {
    initContainer();
    switch (getWebsite().name) {
      case "google":
        googleInjectContainer();
        break;
      case "bing":
        bingInjectContainer();
        break;
      case "baidu":
        baiduInjectContainer();
        break;
      case "duckduckgo":
        duckduckgoInjectContainer();
        break;
      case "deepl":
        deeplInjectContainer();
        break;
      default:
        alertUnknowError();
    }
    function googleInjectContainer() {
      if (getPosition() === 1) {
        const container2 = getContainer();
        const siderbarContainer = document.getElementById("rhs");
        if (siderbarContainer) {
          siderbarContainer.prepend(container2);
        } else {
          container2.classList.add("sidebar-free");
          document.getElementById("rcnt").appendChild(container2);
        }
      } else {
        GM_addStyle(".chat-gpt-container{max-width: 100%!important}");
        const container2 = getContainer();
        const mainContainer = document.querySelector("#search");
        if (mainContainer) {
          mainContainer.prepend(container2);
        }
      }
    }
    function bingInjectContainer() {
      if (getPosition() === 1) {
        const container2 = getContainer();
        const siderbarContainer = document.getElementById("b_context");
        siderbarContainer.prepend(container2);
      } else {
        GM_addStyle(".chat-gpt-container{max-width: 100%!important}");
        GM_addStyle(".chat-gpt-container{width: 70vw}");
        const container2 = getContainer();
        const mainBarContainer = document.querySelector("main");
        mainBarContainer.prepend(container2);
      }
    }
    function baiduInjectContainer() {
      if (getPosition() === 1) {
        const container2 = getContainer();
        const siderbarContainer = document.getElementById("content_right");
        siderbarContainer.prepend(container2);
      } else {
        GM_addStyle(".chat-gpt-container{max-width: 100%!important}");
        const container2 = getContainer();
        const siderbarContainer = document.querySelector("#content_left");
        siderbarContainer.prepend(container2);
      }
    }
    function duckduckgoInjectContainer() {
      const container2 = getContainer();
      const siderbarContainer = document.getElementsByClassName("results--sidebar")[0];
      siderbarContainer.prepend(container2);
    }
    function deeplInjectContainer() {
      const container2 = getContainer();
      container2.style.maxWidth = "1000px";
      const button = document.createElement("button");
      button.innerHTML = i18n("chatGPTTranslate");
      button.className = "chat-gpt-translate-button";
      document.getElementsByClassName("lmt__textarea_container")[0].appendChild(button);
      button.addEventListener("click", function() {
        initContainer();
        button.disabled = true;
        try {
          document.getElementsByClassName("lmt__raise_alternatives_placement")[0].insertBefore(container2, document.getElementsByClassName("lmt__translations_as_text")[0]);
        } catch {
          document.getElementsByClassName("lmt__textarea_container")[1].insertBefore(container2, document.getElementsByClassName("lmt__translations_as_text")[0]);
        }
        let outlang = document.querySelectorAll("strong[data-testid='deepl-ui-tooltip-target']")[0].innerHTML;
        let question = "Translate the following paragraph into " + outlang + " and only " + outlang + "\n\n" + document.getElementById("source-dummydiv").innerHTML;
        getAnswer(question, (t) => {
          button.disabled = false;
        });
      });
    }
  }
  function initMenu() {
    let position_id = GM_registerMenuCommand(i18n("containerPosition") + getPosition(), position_switch, "M");
    function position_switch() {
      GM_unregisterMenuCommand(position_id);
      setPosition((getPosition() + 1) % 2);
      position_id = GM_registerMenuCommand(i18n("containerPosition") + getPosition(), position_switch, "M");
      location.reload();
    }
  }
  async function main() {
    initUI();
    initMenu();
    if (getWebsite().type === "immediately") {
      getAnswer(getQuestion());
    }
  }
  main().catch((e) => {
    console.error(e);
  });
})();