Skip to content

Instantly share code, notes, and snippets.

@FonzTech
Last active July 7, 2025 10:29
Show Gist options
  • Save FonzTech/ce8226dfeeac7a9ec98427d169acfabb to your computer and use it in GitHub Desktop.
Save FonzTech/ce8226dfeeac7a9ec98427d169acfabb to your computer and use it in GitHub Desktop.
Bulk Copy ChatGPT conversation. No plugins required.
/*
Copy-paste this in your browser developer console.
This script works on an already-opened conversation in ChatGPT.
Each message has a "copy" button, that copies markdown text,
which can be placed in MD Editor and exported to PDF.
To automate the task of iterating these buttons and copying
into a file, I created this script that can be configured and
edited further to suit your needs.
IMPORTANT: you must give clipboard permissions in your browser!!
IMPORTANT 2: this script works by continuously clipboard copying
chat contents. To do so, it's required that page "Document" is
focused. So, the entire script is wrapped inside a once-timer.
After you run the script, click the text contents in your chat
to give focus to the "Document" DOM element.
*/
{
// Configuration
// Separator between questions and answers
const qa_separator = '\n---\n'; // '\\newpage\n'
/*
Time increment between clipboard copy buttons, in milliseconds
This value is required because clipboard copy instruction is done via button click callback,
not the bare clipboard copy instruction.
This time depends on your machine and setup. If you find duplicated text after this script
run, you can try increasing this value.
*/
let timeinc = 80;
/*
Initial delay time, in milliseconds.
Just set enough time so you can run the script in your browser console,
then click the page contenets to give focus to its document.
*/
let initdelay = 2000;
// Script
let text = "";
setTimeout(async () => {
let i = 1;
let user = true;
document.querySelectorAll('div.composer-parent button[data-testid="copy-turn-action-button"]').forEach(async (btn) => {
setTimeout(() => {
btn.click();
}, i);
i += timeinc;
setTimeout(async () => {
const contents = await navigator.clipboard.readText();
if (user) {
if (text.length) {
text += qa_separator;
}
text += "**You asked:**\n" + contents + "\n---\n\n";
} else {
text += contents + '\n';
}
user = !user;
}, i);
i += timeinc;
});
i += timeinc;
setTimeout(() => {
navigator.clipboard.writeText(text);
console.log("Successfully copied string with length " + text.length + " in " + i + " ms!");
}, i);
}, initdelay);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment