「Google Gemini で執筆支援」の版間の差分

提供: MeryWiki
ナビゲーションに移動 検索に移動
 
(同じ利用者による、間の1版が非表示)
29行目: 29行目:


<syntaxhighlight lang="javascript" copy>
<syntaxhighlight lang="javascript" copy>
#fonticon = "\uF45E"
#language = "V8"
#language = "V8"
#title = "Gemini で執筆支援"
#title = "Gemini で執筆支援"
46行目: 47行目:
async function callGemini(apiKey, promptText) {
async function callGemini(apiKey, promptText) {
try {
try {
const response = await fetch("https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite-preview-06-17:generateContent?key=" + apiKey, {
const response = await fetch("https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=" + apiKey, {
method: "POST",
method: "POST",
headers: {
headers: {

2025年12月4日 (木) 21:56時点における最新版

概要[編集]

Google の生成 AI「Gemini」を活用した V8 マクロのサンプルです。

テキストを選択した状態でマクロを実行すると、Gemini が文章作成をサポートします。

注意事項[編集]

  • Mery Ver 3.7.8 以上で動作します。
  • Google AI Studio で Gemini API キーを取得してください。
  • Gemini API の特性上、送信した文字列が AI の学習に利用される可能性があります。機密情報やプライバシーに関わる内容は送信しないでください。
  • 本マクロを登録することで、選択したテキストが Google Gemini に送信され処理されることに同意したものとみなします。データの取り扱いについては、Google Gemini の利用規約およびプライバシーポリシーを必ずご確認ください。
  • 2025年6月21日時点で無料の Gemini API を使用しています。ただし、将来の仕様変更や設定ミスにより費用が発生しても、作者は責任を負いません。

使い方[編集]

  • 環境変数の設定
コマンド プロンプトで以下のコマンドを実行し、環境変数を設定してください。
setx GEMINI_API_KEY "***************************************"
設定後、Mery または Windows の再起動が必要な場合があります。
  • マクロの実行
    • テキストを選択し、マクロを実行するとポップアップ メニューが表示されます。
    • [やわらかく書き換えて] や [要約して] など、相談したい項目を選択すると、Gemini API に送信され、結果が出力されます。

ソースコード (AskGemini.js)[編集]

#fonticon = "\uF45E"
#language = "V8"
#title = "Gemini で執筆支援"
#tooltip = "選択範囲を Google Gemini に相談します。"
/*
1. 環境変数の設定
マクロを使用する前に、コマンド プロンプトで以下の環境変数を設定してください。
setx GOOGLE_API_KEY "***************************************"

2. データ利用についての同意
マクロを登録することにより、文書内のテキスト データが Google Gemini に送信され、処理されることに同意したものとみなします。データの取り扱いやプライバシーに関する詳細は、Google Gemini の利用規約およびプライバシーポリシーをご確認ください。
https://support.google.com/gemini?p=privacy_help
*/

// [出力] 0: 選択範囲の後, 1: 新規文書, 2: アウトプット バー
const output = 0;
async function callGemini(apiKey, promptText) {
	try {
		const response = await fetch("https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=" + apiKey, {
			method: "POST",
			headers: {
				"Content-Type": "application/json",
			},
			body: JSON.stringify({
				"contents": [{
					"role": "user",
					"parts": [{
						"text": promptText
					}],
				}],
			}),
		});
		if (!response.ok) {
			alert(await response.text());
			Quit();
		}
		const responseObj = await response.json();
		if (!responseObj.candidates || responseObj.candidates.length === 0) {
			alert("candidates が見つかりませんでした。");
			Quit();
		}
		return responseObj.candidates[0].content.parts[0].text;
	} catch (error) {
		alert(error.message);
		Quit();
	}
}

async function main() {
	const prefix = "次の文章を";
	const rewrite = "書き換え";
	const rewrites = [
		"やわらかく書き換えて",
		"フォーマルに書き換えて",
		"エモーショナルに書き換えて",
		"わかりやすく書き換えて",
		"簡潔に書き換えて",
		"バズるように書き換えて"
	];
	const actions = [
		"要約して",
		"3 行にまとめて",
		"SNS の投稿用にまとめて",
		"文末のまとめを書いて",
		"-",
		"もっと読まれるようにして",
		"間違いを見つけて",
		"反対意見を書いて",
		"炎上しないように確認して"
	];
	const translate = "翻訳";
	const translates = [
		"日本語に翻訳して",
		"英語に翻訳して",
		"中国語に翻訳して",
		"韓国語に翻訳して"
	];
	const ask = "くわしく相談...";
	const send = "そのまま送信";
	const apiKey = shell.getEnv("GEMINI_API_KEY");
	if (!apiKey) {
		alert("API キーが設定されていません。");
		return;
	}
	let sel = document.selection;
	let text = sel.Text;
	if (text.length === 0) {
		alert("テキストが選択されていません。");
		return;
	}
	const menu = CreatePopupMenu();
	const submenu = CreatePopupMenu();
	const submenu2 = CreatePopupMenu();
	const askCommandId = 1001;
	const sendCommandId = 1002;
	let commandId = 0;
	for (let i = 0; i < rewrites.length; ++i) {
		submenu.Add(rewrites[i], ++commandId);
	}
	menu.AddPopup(rewrite, submenu);
	menu.Add("", 0, meMenuSeparator);
	for (let i = 0; i < actions.length; ++i) {
		if (actions[i] === "-") {
			menu.Add("", 0, meMenuSeparator);
		} else {
			menu.Add(actions[i], ++commandId);
		}
	}
	menu.Add("", 0, meMenuSeparator);
	for (let i = 0; i < translates.length; ++i) {
		submenu2.Add(translates[i], ++commandId);
	}
	menu.AddPopup(translate, submenu2);
	menu.Add("", 0, meMenuSeparator);
	menu.Add(ask, askCommandId);
	menu.Add("", 0, meMenuSeparator);
	menu.Add(send, sendCommandId);
	const result = menu.Track(mePosMouse);
	if (result !== 0) {
		let promptText = "";
		if (result === askCommandId) {
			promptText = prompt("Gemini に相談(&A)", "校正してください。", mePromptMultiline).substring(0, 65530);
			if (promptText.length === 0) {
				return;
			}
		} else if (result !== sendCommandId) {
			promptText = menu.GetText(result);
		}
		if (promptText.length !== 0 || text.length !== 0) {
			if (promptText.length === 0) {
				promptText = text;
			} else if (text.length !== 0) {
				promptText = prefix + promptText + ":\n" + text;
			}
			shell.KeepRunning = true;
			status = "Gemini に相談しています...";
			try {
				const response = await callGemini(apiKey, promptText);
				switch (output) {
					case 1:
						editor.NewFile();
						editor.ActiveDocument.write(response);
						break;
					case 2:
						outputBar.writeln(response);
						outputBar.Visible = true;
						break;
					default:
						BeginUndoGroup();
						try {
							sel.CharRight();
							sel.EndOfLine(false, mePosLogical);
							sel.NewLine();
							sel.Text = "\n---\n\n" + response.trim() + "\n\n---\n";
						} finally {
							EndUndoGroup();
						}
						break;
				}
			} catch (error) {
				console.log("Gemini API エラー: ", error);
			} finally {
				status = "";
				shell.KeepRunning = false;
			}
		}
	}
}
main();

カスタマイズ[編集]

  • ソースコードの最初の部分で、output の値を変更することで、Gemini の結果をどこに出力するかを選択できます。
// [出力] 0: 選択範囲の後, 1: 新規文書, 2: アウトプット バー
const output = 0;
  • Gemini へのアクションは、ソースコードの中ほどで actions などの定数に定義されています。文字列を変更または追加することで、お好みのアクションを定義できます。
const actions = [
	"要約して",
	"3 行にまとめて",
	"SNS の投稿用にまとめて",
	"文末のまとめを書いて",
	"-",
	"もっと読まれるようにして",
	"間違いを見つけて",
	"反対意見を書いて",
	"炎上しないように確認して"
];

スペシャルサンクス[編集]

本マクロは、yuko さんが作成された「Google Gemini に相談」マクロにインスパイアされ、Mery のあまり使われていないと思われる V8 マクロ機能を使って実装したサンプルです。yuko さんの素晴らしいアイデアに感謝し、このマクロをお届けします。

スポンサーリンク