├── .gitignore ├── .gitattributes ├── chatgpticon.png ├── document.js ├── MUSTREAD.md ├── index.html ├── manifest.json ├── CONTRIBUTE.md ├── README.md ├── secret.js └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .drawio-chrome 4 | drawio_assets 5 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /chatgpticon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gooddavvy/chatgpt-get-chats-extension/HEAD/chatgpticon.png -------------------------------------------------------------------------------- /document.js: -------------------------------------------------------------------------------- 1 | chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { 2 | if (request.message === 'getDocument') { 3 | sendResponse({ document: document }); 4 | } 5 | }); 6 | -------------------------------------------------------------------------------- /MUSTREAD.md: -------------------------------------------------------------------------------- 1 | # Laws 2 | 3 | ## Laws of Reading Source Code 4 | 5 | - Do not steal any code from this extension repository. 6 | - Do not copy any code from this extension without permission. 7 | - Do not look at `secret.js` unless you are one of the owners/contributors of this extension repository. 8 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ChatGPT Chat Message Extractor 6 | 22 | 23 | 24 |

25 | ChatGPT Chat Message Extractor 26 |

27 |
28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 3, 3 | "name": "ChatGPT Chats Extractor", 4 | "version": "1.0.0", 5 | "description": "ChatGPT Chats Extractor extracts all the messages in correct order from the current chat in ChatGPT", 6 | "icons": { 7 | "16": "chatgpticon.png", 8 | "48": "chatgpticon.png", 9 | "128": "chatgpticon.png" 10 | }, 11 | "author": "David Akins & Sunday Akins ", 12 | "action": { 13 | "default_icon": { 14 | "16": "chatgpticon.png", 15 | "24": "chatgpticon.png", 16 | "32": "chatgpticon.png" 17 | }, 18 | "default_title": "ChatGPT Chats Extractor", 19 | "default_popup": "index.html" 20 | }, 21 | "host_permissions": [ 22 | "https://*/*", 23 | "http://*/*" 24 | ], 25 | "permissions": [ 26 | "activeTab", 27 | "scripting" 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /CONTRIBUTE.md: -------------------------------------------------------------------------------- 1 | # So, how do I contribute to your Chrome Extension? 2 | 3 | First, in order to make changes to our extension, you need to spot a bug. You will also need a GitHub account. You can put it in the Issues tab here on GitHub, and shortly we will reply to your issue comment on GitHub. 4 | 5 | If you receive a reply that says "Accepted." inside of the reply, you can fork our repository and try to fix the issue. Test the extension, you aren't allowed to publish it to Chrome Webstore, and if it resolves the issue you found, you can submit a pull request to our repository, then if we think if it is good, we will merge the pull request you submitted. 6 | 7 | Otherwise, if you receive a reply that says "Not Accepted.", that means that the issue in our extension has either been fixed by ourselves, or the issue is not true. 8 | 9 | Thank you for your contributions, we would love to get support & feedback from you! And if you have any questions, don't hesitate to ask! 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # What is it? 2 | 3 | ![image](chatgpticon.png) 4 | 5 | Our goal is to create a Chrome Extension that extracts all of the messages in correct in a certain ChatGPT chat. It will actually tell you the messages only if you are currently on a tab that says or starts with ["chat.openai.com/chat"](chat.openai.com/chat) no matter how many messages are that. 6 | 7 | And, you must read the [Laws of Reading Source Code](MUSTREAD.md#laws-of-reading-source-code) before looking at the source code. There are some laws. If we find out that you disobey any of the laws, we may comment one of your repos and say something that you may not like. If you don't however have any repos, we may block your GitHub account from us and for at least 14 days. 8 | 9 | ## Can show me a list of your contributors? 10 | 11 | Certainly! Here are a list of our contributors: 12 | 13 | - David Akins ([github @gooddavvy](github.com/gooddavvy)) -- creator 14 | - Sunday Akins ([github @asolpshinning](github.com/asolpshinning)) -- publisher 15 | 16 | ### How can I contribute? 17 | 18 | Please read (CONTRIBUTE.md)[CONTRIBUTE.MD] for details to contribute. 19 | -------------------------------------------------------------------------------- /secret.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * There is some secret, secret functionality (only one line of code) 4 | * That you must NOT look at. 5 | * Do NOT look at the bottom of this file. 6 | * Because that 1 line of code is extremely extremely important but extremely extremely secret. 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | */ 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | document.addEventListener("DOMContentLoaded", main); -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // necessary functions/vars 2 | function Alert(message) { 3 | const modal = document.createElement('div'); 4 | modal.innerHTML = ` 5 |
14 |

${message}

15 | 16 |
17 | `; 18 | 19 | const okButton = modal.querySelector('#ok-btn'); 20 | okButton.addEventListener('click', () => modal.remove()); 21 | 22 | document.body.appendChild(modal); 23 | } 24 | 25 | function Prompt(message) { 26 | const modal = document.createElement('div'); 27 | modal.innerHTML = ` 28 |
37 |

${message}

38 | 39 | 40 | 41 |
42 | `; 43 | 44 | const inputField = modal.querySelector('.js-prompt-input-field'); 45 | const okButton = modal.querySelector('.OK'); 46 | const cancelButton = modal.querySelector('.cancel'); 47 | 48 | okButton.addEventListener('click', () => modal.remove()); 49 | cancelButton.addEventListener('click', () => modal.remove()); 50 | 51 | return new Promise((resolve, reject) => { 52 | okButton.addEventListener('click', () => resolve(inputField.value)); 53 | cancelButton.addEventListener('click', reject); 54 | }).finally(() => modal.remove()); 55 | } 56 | 57 | var browser = { 58 | location: {}, 59 | document: {} 60 | }; 61 | var Chrome = true || {}; 62 | 63 | /* webpage handler */ 64 | // get the current tab 65 | chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { 66 | // get the URL of the current tab 67 | var url = tabs[0].url; 68 | // extract the host from the URL 69 | var host = new URL(url).host; 70 | // check what the host is 71 | console.log(host); 72 | // use the host as needed by setting `browser.location` 73 | async function awaitedFn() { 74 | browser.location = { href: url, host: await host }; 75 | } 76 | awaitedFn(); 77 | }); 78 | 79 | // get the current document 80 | chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { 81 | chrome.scripting.executeScript({ 82 | target: { tabId: tabs[0].id }, 83 | function: function () { 84 | return { document: document }; 85 | } 86 | }, function (result) { 87 | console.log(result[0].result.document); 88 | }); 89 | }); 90 | async function handle() { 91 | var userSignedIn; 92 | var onChatGPT; 93 | if (browser.location.host === "chat.openai.com") { 94 | onChatGPT = true; 95 | while (true) { 96 | userSignedIn = await Prompt("Are you signed in to ChatGPT? (y/n)"); 97 | if (userSignedIn === "y" || userSignedIn === "Y") { 98 | userSignedIn = true; 99 | break; 100 | } else if (userSignedIn === "n" || userSignedIn === "N") { 101 | userSignedIn = false; 102 | break; 103 | } else { 104 | Alert("We couldn't understand your answer. Please try again. Hint: Type in y for yes or n for no."); 105 | } 106 | } 107 | } else { 108 | onChatGPT = false; 109 | } 110 | 111 | return { 112 | userSignedIn, 113 | onChatGPT, 114 | chrome, 115 | }; 116 | } 117 | 118 | 119 | // main script 120 | // main script 121 | function main() { 122 | var { userSignedIn, onChatGPT, chrome } = handle(); 123 | Chrome = chrome; 124 | window.setTimeout(() => { }, 1000); 125 | if (onChatGPT) { 126 | if (userSignedIn) { 127 | // do something if user is signed in 128 | } 129 | } 130 | console.log(JSON.stringify({ userSignedIn, onChatGPT })); 131 | console.log(browser.location.host, browser.location.href); 132 | if (Chrome) { 133 | console.log(Object.entries(Chrome)); 134 | } else { 135 | console.log('Chrome is not defined'); 136 | } 137 | } 138 | 139 | 140 | 141 | 142 | 143 | // run program with the main() function 144 | 145 | // WHAT?! 146 | 147 | /********* 148 | * 149 | * I know you're wondering where we call the main() function. 150 | * 151 | * I know you're wondering how long this takes to scroll down to the bottom. 152 | * It actually takes forever, or maybe just longer than you'd expect/think. 153 | * 154 | * Here's the complicated part: 155 | * 156 | * But actually, But actually 157 | * 158 | * The main() function is never called. 159 | * Even though it looks like it is called on the page, 160 | * 161 | * It isn't. 162 | * 163 | * And that is the complete truth. 164 | * 165 | * 166 | * Scroll to the bottom and see for yourself. 167 | * 168 | * Because it is the complete, complete truth. 169 | * 170 | * THE END. 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | */ 490 | 491 | /** */ 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | /** */ --------------------------------------------------------------------------------