ChatGPT の送信キーの変更

ChatGPTのChatページ

ChatGPT のチャット画面の不満点

もうすっかり市民権を得て、なかった頃には戻れないくらい便利な ChatGPT。みなさんも毎日お使いのことと思います。
私も、これなしには生活できないものとなっています。

使い方の解説やプロンプトの作り方など、最初の頃こそいろいろエンジニアリング的な要素が必要ということでしたが、今となってはそんなこともなく、もっともっと賢くなって相棒としてとても頼れる存在ではないかと思います。

そんな中で、唯一の不満は、チャットに文字を入力している時に、予期せず改行キーが入ってしまって、書きかけの質問を送信してしまうということではないでしょうか?

私も何度も経験あります。不用意な改行を入れないように、質問欄に入力する時はキータッチを気にしてしまい、なんとなく質問するのがちょっとだけ気を使うというか、誤送信が無いように注意してキーを押していました。Grok とか、Microsoft Teams のチャットなんかもそうですよね。改行キーを押してしまって、書きかけを送ってしまうのがプチストレスでした。

それと、今盛んに言われている電力問題。不用意な書きかけ送信でも、答えを返すために信じられないくらいのサーバー側の電力消費があるはずです。

そこで途中で送ってしまわないようにするには、改行キーで送信する機能を取ってしまえばいいのでは...ということで、いつも使っている Chrome で何かできないものか...

Tampermonkey と JavaScript

ChatGPT といろいろ相談しながら、Chrome の拡張機能である Tampermonkey をインストールして、その中に JavaScript を設定してできるようになりました。

ChatGPT の質問欄の入力時に、改行キーは単なる改行にして、送信する時は Ctrl+改行キー(もしくは送信ボタン)という形に変更することができました。

これで文字入力する時に、少し緊張を強いられることがなくなり、いままで以上に ChatGPT との会話に集中できるようになりました。Grok とか、Teams(Web 版)でもできると思いますので、参考としてスクリプトを載せておきます。

方法1(ChatGPT用)

Chrome に拡張機能として、Tampermonkey をインストールしてください。

その上で、Tampermonkey の Dashboard を開き、タブのところにある + 記号で新しいスクリプト入力になりますので、「エディター」のタブのデフォルト表示された内容はすべて削除して、以下のスクリプトをコピペしてください。

2026/05/31 改定版

// ==UserScript==
// @name         ChatGPT Ctrl+Enter Submission (robust v2)
// @namespace    http://tampermonkey.net/
// @version      2.0
// @description  Enter=改行 / Ctrl+Enter=送信 を強制(iframe/Shadow対応 & beforeinput対策)
// @match        https://chatgpt.com/*
// @match        https://chat.openai.com/*
// @grant        none
// @run-at       document-start
// @all-frames   true
// ==/UserScript==

(function () {
  'use strict';

  // 入力欄かどうかをざっくり判定(今後の変更にも強め)
  function isInComposer(ev) {
    const path = ev.composedPath ? ev.composedPath() : [];
    // 代表的な候補:contenteditable textbox / textarea / role="textbox"
    return path.some(el =>
      el && el.nodeType === 1 && (
        el.tagName === 'TEXTAREA' ||
        el.getAttribute?.('contenteditable') === 'true' ||
        el.getAttribute?.('role') === 'textbox'
      )
    );
  }

  // 送信ボタンを探してクリック(候補を広めに)
  function clickSendButton() {
    const doc = document;
    const candidates = [
      // 旧:あなたの元スクリプト
      '#composer-submit-button',
      // よくある data-testid / aria
      'button[data-testid="send-button"]',
      'button[aria-label="Send"]',
      'button[aria-label="送信"]',
      // type=submit
      'form button[type="submit"]',
      // 近辺コンテナ内のボタン一般(最後の保険)
      '[data-testid*="composer"] button',
      '[class*="composer"] button',
    ];
    for (const sel of candidates) {
      const btn = doc.querySelector(sel);
      if (btn && !btn.disabled) { btn.click(); return true; }
    }
    console.warn('[Tampermonkey] 送信ボタンが見つかりません。セレクタ更新が必要かも。');
    return false;
  }

  // 改行を明示挿入
  function insertNewline(active) {
    if (!active) return;
    if (active.tagName === 'TEXTAREA') {
      const start = active.selectionStart, end = active.selectionEnd;
      const val = active.value;
      active.value = val.slice(0, start) + '\n' + val.slice(end);
      active.selectionStart = active.selectionEnd = start + 1;
      return;
    }
    if (active.isContentEditable) {
      const sel = active.ownerDocument.getSelection();
      if (!sel || sel.rangeCount === 0) return;
      const range = sel.getRangeAt(0);
      const br = active.ownerDocument.createElement('br');
      range.deleteContents();
      range.insertNode(br);
      // キャレットをBRの後ろへ
      range.setStartAfter(br);
      range.setEndAfter(br);
      sel.removeAllRanges();
      sel.addRange(range);
      return;
    }
  }

  // beforeinput 対策:Enterで発火する insertParagraph を止める(送信のトリガを消す)
  document.addEventListener('beforeinput', function (e) {
    if (!isInComposer(e)) return;
    // Enter相当:insertParagraph / insertLineBreak が来ることがある
    if (e.inputType === 'insertParagraph' || e.inputType === 'insertLineBreak') {
      // Ctrl+Enter のときは送信、単独Enterは改行に置換(自前で入れる)
      if (e.ctrlKey || e.metaKey) {
        e.preventDefault(); e.stopImmediatePropagation(); e.stopPropagation();
        clickSendButton();
      } else {
        e.preventDefault(); e.stopImmediatePropagation(); e.stopPropagation();
        insertNewline(document.activeElement);
      }
    }
  }, true); // capture

  // keydown でもブロック(二重の安全策)
  document.addEventListener('keydown', function (e) {
    if (e.key !== 'Enter') return;
    if (!isInComposer(e)) return;

    // OS違い考慮:Windows/Linux=Ctrl、macOS=Meta(Command)
    const submitCombo = e.ctrlKey || e.metaKey;

    e.preventDefault();
    e.stopImmediatePropagation();
    e.stopPropagation();

    if (submitCombo) {
      clickSendButton();
    } else {
      insertNewline(document.activeElement);
    }
  }, true); // capture


  // ページロード後、アプリの「Enterで送信」設定らしき属性があれば無効化(あれば…の保険)
  const mo = new MutationObserver(() => {
    // ここで特定の data-attr を発見したら false にする等、将来のフックを追加可能
    // 例: document.querySelector('[data-enter-to-send="true"]')?.setAttribute('data-enter-to-send','false');
  });
  mo.observe(document.documentElement, { subtree: true, childList: true, attributes: true });
})();

その後、「ファイル」→「保存」して Dashboard に戻り、「有効」にしてください。

これで、ChatGPT の質問途中で改行キーを押してしまっても、単なる改行にしかならないので、誤送信される恐れがなくプロンプト作成に集中できます。

ChatGPT への回答の「どうもありがとう」みたいなお礼を送ったりするだけで、結構なサーバ負荷や電力消費になると言われています。この対策によって、書きかけの質問を送ることもなくなり、地球にとってもやさしいものになると思います。ぜひお試しください。

OpenAI さんには、ぜひ送信キーを何にするのかの設定ができるようしていただきたいと思ます。

ただ、動作しないなどのサポートはできませんので、あくまで自己責任でお願いいたします。

方法2(Grok用)

おまけとして、Grok の場合のスクリプトも貼り付けておきます。上記と同じように別ファイルとして保存してお使いください。

// ==UserScript==
// @name Grok Ctrl+Enter Submission
// @namespace http://tampermonkey.net/
// @version 1.1
// @description Prevent Enter from sending in Grok; only allow Ctrl+Enter for submission
// @match https://grok.com/*
// @grant none
// ==/UserScript==

(function () {
'use strict';

document.addEventListener('keydown', function (e) {
const active = document.activeElement;
const isTextarea = active && active.tagName === 'TEXTAREA';

if (!isTextarea || e.key !== 'Enter') return;

// 常に Enter の動作をブロック
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();

if (e.ctrlKey) {
// Ctrl+Enter のとき → 送信ボタンをクリック
const sendButton = document.querySelector('button[type="submit"][aria-label="送信"]:not([disabled])');
if (sendButton) {
sendButton.click();
} else {
console.warn('[Tampermonkey] 送信ボタンが見つからないか、無効です。');
}
} else {
// Enter 単体 → 改行を挿入
const start = active.selectionStart;
const end = active.selectionEnd;
const value = active.value;
active.value = value.substring(0, start) + '\n' + value.substring(end);
active.selectionStart = active.selectionEnd = start + 1;
}
}, true); // キャプチャフェーズ
})();