Created
August 14, 2024 11:39
-
-
Save taktamur/0a54a4d57af5080fc7878e4a618e6922 to your computer and use it in GitHub Desktop.
webページの内容をGPTのAPIを使って要約するuserscript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const API_KEY = 'xxxxxxxx'; // ここにAPIキーを入れる | |
// ==UserScript== | |
// @name GPT Summary Context Menu | |
// @namespace http://tampermonkey.net/ | |
// @version 1.2 | |
// @description Trigger GPT summary via context menu | |
// @author taktamur | |
// @match *://*/* | |
// @grant none | |
// @run-at context-menu | |
// ==/UserScript== | |
// run-at でコンテキストメニュー起動からの起動としている | |
(async function() { | |
'use strict'; | |
// 要約結果を表示するエリアを作成 | |
const summaryDiv = document.createElement('div'); | |
summaryDiv.style.position = 'fixed'; | |
summaryDiv.style.top = '50px'; | |
summaryDiv.style.right = '10px'; | |
summaryDiv.style.width = '300px'; | |
summaryDiv.style.maxHeight = '400px'; | |
summaryDiv.style.overflowY = 'auto'; | |
summaryDiv.style.backgroundColor = '#f9f9f9'; | |
summaryDiv.style.border = '1px solid #ddd'; | |
summaryDiv.style.padding = '10px'; | |
summaryDiv.style.display = 'none'; | |
summaryDiv.style.zIndex = 1000; | |
// 閉じるボタンを作成 | |
const closeButton = document.createElement('button'); | |
closeButton.textContent = '閉じる'; | |
closeButton.style.display = 'block'; | |
closeButton.style.marginTop = '10px'; | |
closeButton.style.backgroundColor = '#f44336'; | |
closeButton.style.color = 'white'; | |
closeButton.style.border = 'none'; | |
closeButton.style.padding = '5px'; | |
closeButton.style.cursor = 'pointer'; | |
// コピーするボタンを作成 | |
const copyButton = document.createElement('button'); | |
copyButton.textContent = 'コピー'; | |
copyButton.style.display = 'block'; | |
copyButton.style.marginTop = '10px'; | |
copyButton.style.backgroundColor = '#008CBA'; | |
copyButton.style.color = 'white'; | |
copyButton.style.border = 'none'; | |
copyButton.style.padding = '5px'; | |
copyButton.style.cursor = 'pointer'; | |
summaryDiv.appendChild(copyButton); | |
summaryDiv.appendChild(closeButton); | |
document.body.appendChild(summaryDiv); | |
// GPT APIを使用して要約を取得する関数 | |
async function getSummary(article) { | |
console.log(article.length); | |
const apiUrl = "https://api.openai.com/v1/chat/completions"; | |
const requestBody = { | |
model: "gpt-4o-mini", | |
messages: [ | |
{ | |
role: "system", | |
content: | |
"これからwebページのテキストを投げます。その内容を箇条書きで要約してください。" + | |
"要約は箇条書きで、5項目程度としてください\n", | |
}, | |
{ | |
role: "user", | |
content: article, | |
}, | |
], | |
max_tokens: 1000, | |
}; | |
try { | |
const response = await fetch(apiUrl, { | |
method: "POST", | |
headers: { | |
Authorization: `Bearer ${API_KEY}`, | |
"Content-Type": "application/json", | |
}, | |
body: JSON.stringify(requestBody), | |
}); | |
if (!response.ok) { | |
throw new Error(`HTTP error! status: ${JSON.stringify(response.status)}`); | |
} | |
const data = await response.json(); | |
const summary = data.choices[0].message.content.trim(); | |
return summary; | |
} catch (error) { | |
console.error("Error summarizing text:", error); | |
throw error; | |
} | |
} | |
// コンテキストメニューに項目を追加 | |
document.addEventListener('click', async () => { | |
}); | |
// 閉じるボタンの処理 | |
closeButton.addEventListener('click', () => { | |
summaryDiv.style.display = 'none'; | |
}); | |
// コピーするボタンの処理 | |
copyButton.addEventListener('click', () => { | |
const textToCopy = summaryDiv.innerText.replace('コピー閉じる', '').trim(); // 要約テキストを取得し、不要なボタンテキストを削除 | |
navigator.clipboard.writeText(textToCopy).then(() => { | |
console.log('要約がコピーされました'); | |
}).catch(err => { | |
console.error('コピーに失敗しました: ', err); | |
}); | |
}); | |
const pageContent = document.body.innerText; // ページ全体のテキストを取得 | |
summaryDiv.textContent = '要約を取得中...'; | |
summaryDiv.style.display = 'block'; | |
try { | |
const summary = await getSummary(pageContent); | |
summaryDiv.innerHTML = summary.replace(/\n/g, '<br>'); | |
summaryDiv.appendChild(copyButton); // コピーするボタンを再度追加 | |
summaryDiv.appendChild(closeButton); // 閉じるボタンを再度追加 | |
} catch (error) { | |
summaryDiv.textContent = '要約の取得に失敗しました。'; | |
summaryDiv.appendChild(copyButton); // エラーの場合もコピーするボタンを追加 | |
summaryDiv.appendChild(closeButton); // エラーの場合も閉じるボタンを追加 | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment