Scrapboxに書いたコンテキストを元にChatGPTにテキストを作ってもらう
public.icon
https://gyazo.com/a8ab9ba00b6cf8a85286e1ac14840780
↑既存の下書きからプレスリリースを生成している様子
できたtkgshn.icon*4
使い方
code:script.js
scrapbox.PopupMenu.addButton({
title: "ChatGPT",
onClick: () => {
const userQuote = window.getSelection().toString(); // ユーザーが選択したテキストを取得
console.log("userQuote", userQuote)
const userInput = prompt("ChatGPTに質問する:"); // promptウィンドウを空で開く
console.log("userInput", userInput)
if (userInput) { // もしuser inputが存在すれば、
const pageContent = scrapbox.Page.lines.map(line => line.text).join('\n'); //ページの内容を結合
console.log("pageContent", pageContent)
console.log(window.askChatGPT); // これは関数が正しく定義されていれば、関数をログに出力します。
askChatGPT({ userInput, userQuote, pageContent }).then((response) => {
if (response.choices && response.choices.length > 0) {
const result = "ChatGPTからの回答" + '\n' + "" + response.choices[0].message.content.trim() + "";
console.log('GPT Response:', result);
//window.chatgpt_result = result; //回答はブラウザのalertで表示する
//alert(result);
// モーダルダイアログを作成
const modal = document.createElement('div');
modal.style.position = 'fixed';
modal.style.top = '50%';
modal.style.left = '50%';
modal.style.transform = 'translate(-50%, -50%)';
modal.style.backgroundColor = 'white';
modal.style.padding = '20px';
modal.style.zIndex = '1000';
modal.style.borderRadius = '5px';
modal.style.boxShadow = '0 4px 6px rgba(0, 0, 0, 0.1)';
// 結果を表示するテキストエリア
const textArea = document.createElement('textarea');
textArea.value = result;
textArea.style.width = '600px';
textArea.style.height = '400px';
// モーダルを閉じるボタン
const closeButton = document.createElement('button');
closeButton.textContent = '閉じる';
closeButton.onclick = function() {
document.body.removeChild(modal);
};
modal.appendChild(textArea);
modal.appendChild(closeButton);
document.body.appendChild(modal);
} else {
console.error('GPT Response Error:', response);
alert('エラーが発生しました。');
}
});
}
},
});
code:GPT.user.js
// ==UserScript==
// @name GPT + Scrapbox
// @version 0.1
// @description try to take over the world!
// @author You
// @grant GM_xmlhttpRequest
// ==/UserScript==
unsafeWindow.askChatGPT = async (
userInput,
userQuote,
pageContent,
{ temperature = 0.7, max_tokens = 500 } = {}
) => {
console.log(window.askChatGPT); // これは関数が正しく定義されていれば、関数をログに出力します。
console.log("Sending request to GPT:", { userInput, userQuote, pageContent }); // リクエスト情報をログに出力
const headers = {
"Content-Type": "application/json",
Authorization: "Bearer " + localStorage.getItem("OPENAI_KEY"),
};
function escapeString(str) {
return str
.replace(/\\/g, "\\\\")
.replace(/"/g, '\\"')
.replace(/\n/g, "\\n")
.replace(/\r/g, "\\r")
.replace(/\t/g, "\\t");
}
if (typeof pageContent === "string") {
pageContent = escapeString(pageContent);
}
if (typeof userInput === "string") {
userInput = escapeString(userInput);
}
if (typeof userQuote === "string") {
userQuote = escapeString(userQuote);
}
console.log("data", userQuote, userInput, pageContent);
console.log(typeof userInput);
if (userInput === null) {
console.log("userInput is NULL");
}
const data = JSON.stringify({
model: "gpt-3.5-turbo",
temperature: temperature,
max_tokens: max_tokens,
messages: [
{
role: "system",
content:
"あなたはScrapboxのページと密接に統合されたエージェントです。ユーザーはScrapboxに日記や議事録、そのほかWebからのまとめなどを日々書いています。「ユーザーが選択したテキスト(userQuote)」に対して『ユーザーからの指示(userInput)』が投げられています。*指示の通りに最小限で明確な返答をしてください。返事は指示を達成するためだけに使用することにしてください。*コンテキストはScrapboxページの全文(pageContent)を参照してください",
},
{
role: "user",
content: "userInput: " + userInput.userInput,
},
{
role: "user",
"content": "userQuote: " + userInput.userQuote,
},
{
role: "user",
"content": "pageContent: " + userInput.pageContent,
},
],
});
console.log(data);
return await new Promise((resolve, reject) =>
GM_xmlhttpRequest({
method: "POST",
data,
headers,
onload: (response) => {
console.log("GPT Response:", response.responseText); // GPTからの応答をログに出力
resolve(JSON.parse(response.responseText));
},
responseType: "json",
onerror: (e) => {
console.error("GPT Request Error:", e); // エラーをログに出力
reject(e);
},
})
);
};
3. APIキーをローカルストレージに保存
ブラウザのdeveloper toolsを開いて、consoleにlocalStorage.setItem('OPENAI_KEY', 'ここにキーを入れる');を入力
参考
そのほか、やりたいこと(教えて)
ChatGPTの回答をinsertする方法がわからない
pageContentに関連リンクも含めたい
作るきっかけ
Scrapboxに議事録などをはじめとしたすべての情報があるのだから、外部向けのコミュニケーション(お礼のメールを書くなど)をAIを使って簡単にやりたい。ChatGPTを使ったScrapboxの拡張を作ることにした。
scrapboxには文字を選択したらホバーする(画像はnew page, copy plainがある)のだが、これに新しく「ChatGPTと対話」という選択肢を付け加えたい。
起こることは、ページの全体のコンテキストを読み込む。関連リンクのものも余裕があればば読み込む。その次に指示を入力するtext fieldがブラウザのpromptメゾットで表示される。