您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Retrieves the titles and unique identifiers of conversations in ChatGPT's web interface. Intended for listing and organization purposes only.
// ==UserScript== // @name ChatGPT Conversation Lister // @namespace https://moukaeritai.work/chatgpt-conversation-lister // @version 0.8.3.20231006 // @description Retrieves the titles and unique identifiers of conversations in ChatGPT's web interface. Intended for listing and organization purposes only. // @author Takashi SASAKI https://twitter.com/TakashiSasaki // @match https://chat.openai.com/ // @match https://chat.openai.com/c/* // @icon https://www.google.com/s2/favicons?sz=64&domain=openai.com // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @grant GM_listValues // @license MIT // ==/UserScript== (function() { 'use strict'; const hostDiv = document.createElement('div'); //container.id = "tampermonkeyDialogDiv"; document.body.appendChild(hostDiv); const shadowRoot = hostDiv.attachShadow({mode: 'open'}); const containerDiv = document.createElement("div"); containerDiv.id = "containerDiv"; shadowRoot.appendChild(containerDiv); document.addEventListener('keydown', function(e) { console.log(e); if (e.key === 'Escape') { while(containerDiv.firstChild){ containerDiv.removeChild(containerDiv.firstChild); }//while }//if }); function createDialogDiv(){ // ダイアログ要素を作成 const dialogDiv = document.createElement('div'); dialogDiv.id = "dialogDiv"; dialogDiv.style.cssText = ` position: fixed; top: 10%; left: 10%; width: 80%; height: 80%; max-height:80%; background: white; padding: 10px; border: 1px solid black; z-index: 10000; border-radius: 15px; box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.5); overflow: auto; line-height: 1.7em; `; dialogDiv.innerHTML = `<style> a:link, a:visited a{ color: inherit; text-decoration: none; background-color: #d9ffaf; margin-left : 0.5em; margin-right: 0.5em; margin-top: 0.5em; margin-bottom: 0.5em; border-radius: 10px; padding: 1px; padding-left: 6px; padding-right: 6px; box-shadow: 2px 2px 3px rgba(0,0,0,0.4); </style>`; containerDiv.appendChild(dialogDiv); return dialogDiv; }//createDialogDiv function createTextarea(){ var textarea = document.createElement('textarea'); textarea.setAttribute("readonly", "readonly"); textarea.style.cssText = ` position: fixed; top: 10%; left: 10%; width: 80%; height: 80%; max-height:80%; background: white; padding: 10px; border: 1px solid black; z-index: 10000; border-radius: 15px; box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.5); overflow: auto; `; textarea.addEventListener("dblclick", (event)=>{ event.target.select(); document.execCommand('copy'); }); containerDiv.appendChild(textarea); return textarea; }//createTextarea const selector20230827 = "#__next > div > div > div.overflow-hidden.w-full.h-full.relative.flex.z-0 > div > div > div > div > nav > div.flex-col > div > div"; const selector20230828 = "#__next > div > div > div.overflow-hidden.w-full.h-full.relative.flex.z-0 > div > div > div > div > nav > div.flex-col.overflow-y-auto"; const selector20230829 = "#__next > div.overflow-hidden.w-full.h-full > div > div > div > div > nav > div.overflow-y-auto"; const conversationListDivErrorMessage = "Unable to retrieve the conversation list. This may be due to changes in the DOM structure of ChatGPT. Please await updates to the ChatGPT Conversation Lister."; const conversationListDiv = selector20230829; var lastScrollTop = 0; var originalScrollHeight = 0; var observer = null; GM_registerMenuCommand("Continuous scrolling on conversation list", ()=>{ const div = document.querySelector(conversationListDiv); if(!div){ alert(conversationListDivErrorMessage); return; }//if const style = window.getComputedStyle(div); console.log(style); if(style.overflowY === 'auto'|| style.overflowY === 'visible') { console.log(style.overflowY); if(!observer) { observer = new MutationObserver((mutationList, observer)=>{ mutationList.forEach(mutation=>{ //if(mutation.target !== div) return; //console.log(mutation.target); if(lastScrollTop != div.scrollTop) { console.log("lastScrollTop", lastScrollTop, "scrollTop", div.scrollTop); lastScrollTop = div.scrollTop; setTimeout(()=> {div.scrollTop = div.scrollHeight}, 500); setTimeout(()=> {div.scrollTop = div.scrollHeight}, 1000); setTimeout(()=> {div.scrollTop = div.scrollHeight}, 2000); setTimeout(()=> {div.scrollTop = div.scrollHeight}, 4000); setTimeout(()=> {div.scrollTop = div.scrollHeight}, 8000); updateConversationList(); }//if });//forEach });//MutationObserver }//if observer.observe(div, { childList : true, attributes: true, subtree: true }); originalScrollHeight = div.scrollHeight; console.log("originalScrollHeight", originalScrollHeight); setTimeout(()=> {div.scrollTop = div.scrollHeight * 2}, 200); setTimeout(()=> {div.scrollTop = div.scrollHeight * 3}, 300); setTimeout(()=> {div.scrollTop = div.scrollHeight * 4}, 400); }//if });//GM_registerMenuCommand GM_registerMenuCommand("Search in titles of conversations", searchForTitle); const searchForTitleButton = document.createElement("img"); searchForTitleButton.setAttribute("src", "https://moukaeritai-static.glitch.me/svg/search-in-title-icon.svg"); searchForTitleButton.style.background="lightyellow"; searchForTitleButton.addEventListener("click", searchForTitle); document.querySelector("nav a.flex").insertAdjacentElement("afterend", searchForTitleButton); function searchForTitle (){ updateConversationList(); const dialogDiv = createDialogDiv(); const input = document.createElement("input"); //input.style.position = "absolute"; input.addEventListener("keyup", event => { setTimeout(()=>{ const nodeList = dialogDiv.querySelectorAll("a"); for(var i=0; i<nodeList.length; ++i){ if(nodeList[i].textContent.toLowerCase().indexOf(input.value.toLowerCase()) == -1){ nodeList[i].style.display = "none"; } else { nodeList[i].style.display = ""; }//if }//for }, 0); //setTimeout }); //addEventListener dialogDiv.appendChild(input); const idArray = GM_listValues(); const objects = idArray.map( id=>GM_getValue(id)); objects.sort( (a,b) => a.projectionId - b.projectionId); objects.forEach( object =>{ const a = document.createElement("a"); a.setAttribute("href", "https://chat.openai.com/c/" + object.id); a.innerText = object.title; dialogDiv.appendChild(a); });//forEach }//searchForTitle GM_registerMenuCommand("List conversations in TSV", ()=>{ updateConversationList(); const textarea = createTextarea(); const idArray = GM_listValues(); const tsv = idArray.map( id =>{ const conversation = GM_getValue(id); return [conversation.id, conversation.title, conversation.projectionId]; });//map const tsvSorted = tsv.sort( (a,b) => { return parseInt(a[2] - parseInt(b[2])); }//sort ); const tsvJoined = tsvSorted.map((x)=> x.join("\t")); textarea.value = tsvJoined.join("\n"); });//GM_registerMenuCommand function updateConversationList(){ //const div = document.querySelector("#__next div nav div div"); //const div = document.querySelector("#__next > div.overflow-hidden.w-full.h-full.relative.flex.z-0 > div.flex-shrink-0.overflow-x-hidden > div > div > div > nav > div.flex-col > div > div"); //const selector20230810 = "#__next > div.overflow-hidden.w-full.h-full.relative.flex > div.dark.flex-shrink-0.overflow-x-hidden > div > div > div > nav > div.overflow-y-auto"; const div = document.querySelector(conversationListDiv); if(!div){ alert(conversationListDivErrorMessage); return; } const liNodes = div.querySelectorAll("li"); console.log(liNodes); liNodes.forEach((li)=>{ console.log(li); for (var key in li) { if (key.startsWith('__reactProps')) { const id = li[key].children.props.id; const title = li[key].children.props.title; const projectionId = li.dataset.projectionId; console.log(id, title,projectionId); if(!id) continue; if(!title) continue; GM_setValue(id, {id:id, title:title, projectionId:projectionId}); }//if }//for });//forEach }//updateConversationList // Your code here... })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址