Minimal ChatGPT Message Logger + Injector + Submitter

Listen for postMessage from parent, log to console, enter it into the chat input, and submit

当前为 2025-05-26 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Minimal ChatGPT Message Logger + Injector + Submitter
  3. // @description Listen for postMessage from parent, log to console, enter it into the chat input, and submit
  4. // @match https://chatgpt.com/*
  5. // @version 0.0.1.20250526025013
  6. // @namespace https://greasyfork.org/users/1435046
  7. // ==/UserScript==
  8.  
  9. (function () {
  10. 'use strict';
  11.  
  12. window.addEventListener('message', function (event) {
  13.  
  14. // Handle search button clicks
  15. if (event.data && event.data.type === 'searchButtonClicked') {
  16. const searchBtn1 = document.querySelector('[data-testid="composer-button-search"]');
  17.  
  18. const searchButton2 = document.getElementById('system-hint-button');
  19.  
  20. if (searchBtn1) {
  21. searchBtn1.click();
  22. return;
  23. }
  24.  
  25. if (searchButton2) {
  26. searchButton2.focus(); // Sometimes needed to simulate a real user
  27. searchButton2.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true }));
  28.  
  29. document.querySelector('[id^="radix-"] > div > div:nth-of-type(2)').click()
  30.  
  31. };
  32. return;
  33. }
  34.  
  35. if (event.data && event.data.type === 'reasonButtonClicked') {
  36. const reasonBtn1 = document.querySelector('[data-testid="composer-button-reason"]');
  37.  
  38. const reasonButton2 = document.getElementById('system-hint-button');
  39.  
  40. if (reasonBtn1) reasonBtn1.click();
  41.  
  42. if (reasonButton2) {
  43. reasonButton2.focus(); // Sometimes needed to simulate a real user
  44. reasonButton2.dispatchEvent(new PointerEvent('pointerdown', { bubbles: true }));
  45.  
  46. document.querySelector('[id^="radix-"] > div > div:nth-of-type(5)').click()
  47. }
  48. return;
  49. }
  50.  
  51. if (event.data && event.data.type === 'newChatButtonClicked') {
  52. // Click the "New chat" anchor link
  53. const newChatLink = document.querySelector('a[aria-label="New chat"][href="/"]');
  54. if (newChatLink) newChatLink.click();
  55. return;
  56. }
  57.  
  58. if (event.data.type !== 'prompt') return;
  59.  
  60. // Locate ProseMirror composer
  61. const composer = document.querySelector('.ProseMirror');
  62. if (!composer) return;
  63.  
  64. console.log('Injecting message:', event.data.content);
  65.  
  66. // Focus and inject the text
  67. composer.focus();
  68.  
  69. const lines = event.data.content.split('\n');
  70. const html = lines
  71. .map(line => `<p>${line
  72. .replace(/&/g, '&amp;')
  73. .replace(/</g, '&lt;')
  74. .replace(/>/g, '&gt;')}</p>`)
  75. .join('');
  76. composer.innerHTML = html;
  77.  
  78. composer.dispatchEvent(new InputEvent('input', { bubbles: true }));
  79.  
  80. // Observe DOM changes until the send button is enabled
  81. const observer = new MutationObserver(function (mutations, obs) {
  82. const sendBtn = document.querySelector('[data-testid="send-button"]');
  83. if (sendBtn && !sendBtn.disabled) {
  84. obs.disconnect();
  85. console.log('Submitting message');
  86. sendBtn.click();
  87. }
  88. });
  89.  
  90. observer.observe(document, {
  91. childList: true,
  92. subtree: true,
  93. attributes: true,
  94. attributeFilter: ['disabled']
  95. });
  96. });
  97. })();