-
Notifications
You must be signed in to change notification settings - Fork 30
/
bookmarklet.js
1 lines (1 loc) · 4.01 KB
/
bookmarklet.js
1
javascript:const styles={toggleUI:"\n position: fixed; \n bottom: 20px; \n right: 20px; \n padding: 10px; \n background-color: #007BFF; \n border: none; \n border-radius: 50%; \n color: white; \n font-weight: bold; \n box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25); \n cursor: pointer; \n z-index: 10000;\n ",downloadWidget:"\n position: fixed;\n bottom: 10px;\n right: 10px;\n background: #fff;\n border: 1px solid #ccc;\n padding: 20px;\n border-radius: 10px;\n z-index: 9999;\n width: 300px;\n box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n "},toggleUIHTML=`\n<button id="toggle-openai-ui" style="${styles.toggleUI}">⏬</button>\n`,uiHTML=`\n<div id="openai-download-widget" style="${styles.downloadWidget}">\n <div style="margin-bottom: 15px">\n <label for="numConversations" style="display: block; margin-bottom: 5px; font-weight: 600">Number of conversations:</label>\n <input type="number" id="numConversations" value="50" style="width: 100%; padding: 5px; border: 1px solid #ccc; border-radius: 5px; box-sizing: border-box;" />\n </div>\n <div style="margin-bottom: 15px">\n <label for="openai-download-progress" style="display: block; margin-bottom: 5px; font-weight: 600">Download Progress:</label>\n <progress id="openai-download-progress" value="0" max="100" style="width: 100%; height: 15px; border-radius: 5px"></progress>\n </div>\n <div style="text-align: left">\n <button id="openai-start-download" style="padding: 10px 15px; background-color: #007bff; color: #fff; border: none; border-radius: 5px; cursor: pointer;">Start Download</button>\n </div>\n</div>\n`;document.body.insertAdjacentHTML("beforeend",toggleUIHTML+uiHTML);const toggleUIVisibility=()=>{const o=document.getElementById("openai-download-widget");o.style.display="none"===o.style.display?"block":"none"};function constructUrlWithParams(o,e){const t=new URL(o);return Object.keys(e).forEach((o=>t.searchParams.append(o,e[o]))),t.toString()}document.getElementById("toggle-openai-ui").addEventListener("click",toggleUIVisibility),document.getElementById("openai-start-download").addEventListener("click",(async()=>{const o=parseInt(document.getElementById("numConversations").value,10);if(o&&o>0){document.getElementById("openai-start-download").disabled=!0;try{await downloadConversationsAsJson(o),console.log("Download completed.")}catch(o){console.error("An error occurred:",o)}document.getElementById("openai-start-download").disabled=!1}else alert("Please enter a valid number of conversations.")}));const conversationsPerRequest=50,delay=63e3;async function fetchData(o,e={}){try{const t=await fetch(o,{headers:e});if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);return await t.json()}catch(e){throw console.error(`Error fetching data from ${o}:`,e),e}}async function fetchAccessToken(){return(await fetchData("https://chat.openai.com/api/auth/session")).accessToken}async function fetchConversationsData(o,e,t){const n=constructUrlWithParams("https://chat.openai.com/backend-api/conversations",{offset:t,limit:e,order:"updated"});return(await fetchData(n,{Authorization:`Bearer ${o}`})).items}async function fetchConversationData(o,e){return fetchData(`https://chat.openai.com/backend-api/conversation/${e}`,{Authorization:`Bearer ${o}`})}async function downloadConversationsAsJson(o){const e=[],t=await fetchAccessToken(),n=Math.ceil(o/conversationsPerRequest);for(let a=0;a<n;a++){const r=a*conversationsPerRequest,s=a===n-1?o-r:conversationsPerRequest,i=await fetchConversationsData(t,s,r);for(let n=0;n<i.length;n++){const r=i[n],s=await fetchConversationData(t,r.id);e.push(s);const d=(a*conversationsPerRequest+n+1)/o*100;document.getElementById("openai-download-progress").value=d}a<n-1&&await new Promise((o=>setTimeout(o,delay)))}const a=new Blob([JSON.stringify(e)],{type:"application/json"}),r=document.createElement("a");r.href=URL.createObjectURL(a),r.download="chatgpt_bookmarklet_download.json",document.body.appendChild(r),r.click(),document.body.removeChild(r)}