Skip to content

Instantly share code, notes, and snippets.

@wardboumans
Last active June 4, 2024 18:45
Show Gist options
  • Save wardboumans/b523647ac016579d8e6b52a67f73c377 to your computer and use it in GitHub Desktop.
Save wardboumans/b523647ac016579d8e6b52a67f73c377 to your computer and use it in GitHub Desktop.
OpenAI summarization button for Inoreader.com rssreader
// ==UserScript==
// @name AI Summary for Inoreader
// @namespace http://tampermonkey.net/
// @version 1.4
// @description Adds a button on Inoreader and summarizes the article with OpenAI
// @author Ward Boumans
// @match https://www.inoreader.com/article/*
// @grant none
// @require https://cdn.jsdelivr.net/npm/marked/marked.min.js
// ==/UserScript==
(function() {
'use strict';
const apiKey = "<APIKEY>";
// Function to create the new button
function createButton() {
const newButton = document.createElement('div');
newButton.className = 'article_footer_buttons star_img icon16 icon-bubble';
newButton.title = 'Summarize with AI (Hotkey: C)';
newButton.id = 'custom_button';
newButton.addEventListener('click', async function() {
const article = document.getElementsByClassName("article_content");
if (article.length === 1) {
const text = article[0].innerText;
const summaryDiv = document.querySelector('.article_sub_title');
if (summaryDiv) {
summaryDiv.classList.add("article_content");
summaryDiv.classList.remove("flex");
summaryDiv.classList.remove("article_sub_title");
summaryDiv.textContent = '✨ working...';
await summarizeArticle(text, summaryDiv);
} else {
alert('Could not find element with class "article_sub_title"');
}
}
});
return newButton;
}
async function summarizeArticle(text, summaryDiv) {
const controller = new AbortController();
const signal = controller.signal;
try {
const response = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${apiKey}`,
},
body: JSON.stringify({
model: "gpt-3.5-turbo", // Choose your desired model
messages: [
{ role: "user", content: "Give short summary of the following text in 10 or less bullet points. Only output the summary without additional text: " + JSON.stringify(text) }
],
max_tokens: 150, // Adjust max summary length
stream: true, // Enable streaming
}),
signal,
});
if (!response.ok) {
throw new Error(`API Error: ${response.status}`);
}
const decoder = new TextDecoder();
var buffer = '✨ Summary:\n\n';
// Iterate through the chunks in the response body using for-await...of
for await (const chunk of response.body) {
const decodedChunk = decoder.decode(chunk);
// Clean up the data
const lines = decodedChunk
.split("\n")
.map((line) => line.replace("data: ", ""))
.filter((line) => line.length > 0)
.filter((line) => line !== "[DONE]")
.map((line) => JSON.parse(line));
for (const line of lines) {
const {
choices: [
{
delta: { content },
},
],
} = line;
if (content) {
buffer += content;
summaryDiv.innerHTML = marked.parse(buffer);
}
}
}
}
catch (error) {
console.error("Error:", error);
summaryDiv.textContent = "Error: Something went wrong with the summarization.";
} finally {
controller.abort();
}
}
// Function to append the button to the toolbar
function appendButtonToToolbar() {
const toolbar = document.querySelector('.article_footer_main_buttons');
if (toolbar && !document.querySelector('#custom_button')) {
const newButton = createButton();
toolbar.appendChild(newButton);
}
}
// Function to check if the toolbar is available and append the button
function checkAndAddButton() {
const toolbar = document.querySelector('.article_footer_main_buttons');
if (toolbar) {
appendButtonToToolbar();
}
}
// Initial check
checkAndAddButton();
// Observe changes to the DOM for SPA navigation
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.addedNodes.length || mutation.removedNodes.length) {
checkAndAddButton();
}
});
});
// Start observing the body for added nodes
observer.observe(document.body, { childList: true, subtree: true });
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment