Greasy Fork is available in English.
自动化 Gemini 操作:模型选择、切换临时对话、自动填充提示词,并支持經由 URL 参数自动发送。
// ==UserScript==
// @name Gemini Toolkit
// @name:zh-TW Gemini 自動化工具箱
// @name:zh-CN Gemini 自动化工具箱
// @author WellsTsai
// @namespace wellstsai.com
// @version v20251218
// @description Automates Gemini: Model selection, temporary chat toggling, prompt auto-filling, and optional auto-sending via URL parameters.
// @description:zh-TW 自動化 Gemini 操作:模型選擇、切換臨時對話、自動填入提示詞,並支援經由 URL 參數自動發送。
// @description:zh-CN 自动化 Gemini 操作:模型选择、切换临时对话、自动填充提示词,并支持經由 URL 参数自动发送。
// @match https://gemini.google.com/*
// @grant none
// @run-at document-end
// @license MIT
// ==/UserScript==
/**
* === Usage Examples ===
*
* 1. Auto-fill text only (Draft mode):
* https://gemini.google.com/app?q=Hello+World
*
* 2. Auto-fill and SEND immediately:
* https://gemini.google.com/app?q=Hello+World&send=true
*
* 3. Switch to specific model (e.g., Gemini Advanced) and fill text:
* https://gemini.google.com/app?q=Analyze+this&model=2
*
* 4. Use Temporary Chat + Model 2 + Auto-send:
* https://gemini.google.com/app?q=Code+review&model=2&temporary-chat=true&send=true
*
* 5. Enable Temporary Chat ONLY (No text, no model switch):
* https://gemini.google.com/app?temporary-chat=true
*/
(function() {
'use strict';
// --- Configuration ---
const CONFIG = {
START_DELAY: 0,
TEMP_CHAT_DELAY: 0,
MODEL_SWITCH_DELAY: 0,
TYPE_TO_SEND_DELAY: 0,
WAIT_TIMEOUT: 10000
};
// --- Parse URL Parameters ---
const params = new URLSearchParams(window.location.search);
const query = params.get('q');
const modelParam = parseInt(params.get('model'), 10);
const modelIndex = (isNaN(modelParam) || modelParam < 1) ? null : modelParam;
const isTempChat = params.get('temporary-chat') === 'true';
const shouldAutoSend = params.get('send') === 'true';
// Exit early if nothing to do
if (!query && !modelIndex && !isTempChat) return;
// --- Helpers ---
const wait = (selector) => {
return new Promise((resolve) => {
const timer = setInterval(() => {
const el = document.querySelector(selector);
if (el) {
clearInterval(timer);
resolve(el);
}
}, 100);
setTimeout(() => clearInterval(timer), CONFIG.WAIT_TIMEOUT);
});
};
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
const aggressiveClick = (el) => {
['pointerdown', 'pointerup', 'mousedown', 'click'].forEach(type => {
const eventClass = type.startsWith('pointer') ? PointerEvent : MouseEvent;
el.dispatchEvent(new eventClass(type, { bubbles: true, cancelable: true }));
});
};
const cleanUrl = () => {
const newUrl = `${window.location.origin}${window.location.pathname}`;
window.history.replaceState({}, '', newUrl);
};
// --- Actions ---
const toggleTempChat = async () => {
if (!isTempChat) return false;
try {
const tempBtn = await wait('button[data-test-id="temp-chat-button"]');
console.log("[Gemini Enhancement] Activating Temporary Chat...");
aggressiveClick(tempBtn);
return true;
} catch (e) {
console.warn("[Gemini Enhancement] Temp Chat toggle failed", e);
return false;
}
};
const switchModel = async () => {
if (!modelIndex) return false;
try {
const menuTrigger = await wait('[data-test-id="bard-mode-menu-button"]');
menuTrigger.click();
await sleep(500);
const overlay = document.querySelector('.cdk-overlay-container');
if (!overlay) return false;
const options = overlay.querySelectorAll('button[role="menuitemradio"]');
const targetBtn = options[modelIndex - 1];
if (!targetBtn || targetBtn.getAttribute('aria-checked') === 'true') {
document.body.click(); // Close menu
return false;
}
console.log(`[Gemini Enhancement] Switching to Model Index: ${modelIndex}`);
aggressiveClick(targetBtn);
return true;
} catch (e) {
console.warn("[Gemini Enhancement] Model switch failed", e);
return false;
}
};
const fillAndSend = async () => {
if (!query) return;
console.log("[Gemini Enhancement] Inputting text...");
const promptBox = await wait('div[contenteditable="true"]');
promptBox.focus();
document.execCommand('insertText', false, query);
promptBox.dispatchEvent(new Event('input', { bubbles: true }));
if (!shouldAutoSend) {
console.log("[Gemini Enhancement] Draft created. Waiting for manual send.");
cleanUrl();
return;
}
await sleep(CONFIG.TYPE_TO_SEND_DELAY);
const sendButton = document.querySelector('.send-button');
if (sendButton && sendButton.getAttribute('aria-disabled') !== 'true') {
console.log("[Gemini Enhancement] Auto-sending...");
aggressiveClick(sendButton);
cleanUrl();
}
};
// --- Main ---
const main = async () => {
await sleep(CONFIG.START_DELAY);
if (await toggleTempChat()) {
await sleep(CONFIG.TEMP_CHAT_DELAY);
}
if (await switchModel()) {
await sleep(CONFIG.MODEL_SWITCH_DELAY);
}
await fillAndSend();
};
if (document.readyState === 'complete') {
main();
} else {
window.addEventListener('load', main);
}
})();