Miniflux automatically refresh feeds

Automatically refreshes Miniflux feeds

  1. // ==UserScript==
  2. // @name Miniflux automatically refresh feeds
  3. // @namespace https://reader.miniflux.app/
  4. // @version 21
  5. // @description Automatically refreshes Miniflux feeds
  6. // @author Tehhund
  7. // @match *://*.miniflux.app/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=miniflux.app
  9. // @run-at document-start
  10. // ==/UserScript==
  11.  
  12. let apiKey = ''; // Put your API key from Miniflux here.
  13. const rateLimit = 43200000; // Only refresh twice per day. 43200000 miliseconds = 12 hours. If a feed has an error (e.g., too many requests) its checked_at datetime still gets updated so we won't hit the feeds with too many requests.
  14.  
  15. const refreshFeeds = async () => {
  16. let toastDiv = document.createElement('div');
  17. toastDiv.id = 'toastDiv';
  18. toastDiv.style.marginBottom = "5rem";
  19. document.body.appendChild(toastDiv);
  20. setTimeout(() => { toastDiv.remove() }, 900000); // remove after 15 minutes.
  21. if (!apiKey) { // If the API key isn't specified, try getting it from localstorage.
  22. apiKey = localStorage.getItem('miniFluxRefresherApiKey');
  23. } else { // If we have the API key, store it in localstorage.
  24. localStorage.setItem('miniFluxRefresherApiKey', apiKey);
  25. }
  26. let req = await fetch('https://reader.miniflux.app/v1/feeds', { headers: { 'X-Auth-Token': apiKey } });
  27. let res = JSON.parse(await req.text());
  28. let feedsArray = res.map(currentFeed => currentFeed); // Turn JSON into an array for sorting.
  29. feedsArray.sort((a, b) => { return (new Date(a.checked_at) - new Date(b.checked_at)) }); // Sort from least recently checked to most recently checked so least recent gets refreshed first.
  30. for (let [index, feed] of feedsArray.entries()) {
  31. let lastChecked = new Date(feed.checked_at).getTime();
  32. if (Date.now() - lastChecked > rateLimit) {
  33. console.log(`It's been more than 12 hours, refresh.`);
  34. setTimeout(
  35. async () => {
  36. let req = await fetch(`https://reader.miniflux.app/v1/feeds/${feed.id}`, { headers: { 'X-Auth-Token': apiKey } });
  37. let response = JSON.parse(await req.text());
  38. let lastChecked = new Date(response.checked_at).getTime();
  39. if (Date.now() - lastChecked > rateLimit) { // Since navigating, refreshing the page, or using another device could cause duplicate refreshes, double check that each feed still hasn't been refreshed recently.
  40. let newNode = setToast(`Fetching ${feed.title} ${feed.site_url}.`);
  41. let res = await fetch(`https://reader.miniflux.app/v1/feeds/${feed.id}/refresh`, {
  42. method: "PUT",
  43. headers: { 'X-Auth-Token': apiKey }
  44. });
  45. newNode.textContent += ` Complete.`;
  46. console.log(res);
  47. }
  48. }, 15000 * index); // Make a call every 15 seconds.}
  49. } else console.log(`It's been less than 12 hours, do nothing.`);
  50. }
  51. }
  52.  
  53. const setToast = (text) => {
  54. let newNode = document.createElement('div');
  55. newNode.id = `feedFetchStatus`;
  56. newNode.textContent = text;
  57. document.getElementById('toastDiv').appendChild(newNode);
  58. setTimeout(() => { newNode.remove() }, 4000);
  59. return newNode;
  60. }
  61.  
  62. // run once when the page is loaded.
  63. window.addEventListener("DOMContentLoaded", refreshFeeds);