mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-05 19:24:39 +00:00
152 lines
5.3 KiB
TypeScript
152 lines
5.3 KiB
TypeScript
import Parser from "rss-parser";
|
|
|
|
/**
|
|
* Fetches news articles specifically for Australia from the NewsAPI.
|
|
*
|
|
* This function handles a specific case for fetching Australian news. It includes a
|
|
* mechanism to retry the fetch operation by appending "%00" to the URL if a
|
|
* rate limit error (`response.code == "rateLimited"`) is encountered. This is
|
|
* likely a workaround for cache-busting or bypassing certain rate-limiting measures.
|
|
*
|
|
* @param {string} url The NewsAPI URL to fetch Australian news from.
|
|
* @param {any} sendResponse A callback function (likely from a browser extension message listener)
|
|
* to send the fetched news data back to the caller.
|
|
* It's called with an object like `{ news: responseData }`.
|
|
*/
|
|
const fetchAustraliaNews = async (url: string, sendResponse: any) => {
|
|
fetch(url)
|
|
.then((result) => result.json())
|
|
.then((response) => {
|
|
if (response.code == "rateLimited") {
|
|
fetchAustraliaNews((url += "%00"), sendResponse);
|
|
} else {
|
|
sendResponse({ news: response });
|
|
}
|
|
});
|
|
};
|
|
|
|
/**
|
|
* A record mapping lowercase country codes (e.g., "usa", "canada") to an array
|
|
* of RSS feed URLs for news sources in that country.
|
|
*
|
|
* @type {Record<string, string[]>}
|
|
*/
|
|
const rssFeedsByCountry: Record<string, string[]> = {
|
|
usa: [
|
|
"https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml",
|
|
"https://www.huffpost.com/section/front-page/feed",
|
|
"https://www.npr.org/rss/rss.php",
|
|
],
|
|
taiwan: [
|
|
"https://news.ltn.com.tw/rss/all.xml",
|
|
"https://www.taipeitimes.com/xml/index.rss",
|
|
"https://international.thenewslens.com/rss",
|
|
],
|
|
hong_kong: [
|
|
"https://rthk9.rthk.hk/rthk/news/rss/e_expressnews_elocal.xml",
|
|
"https://www.scmp.com/rss/91/feed",
|
|
],
|
|
panama: [
|
|
"https://critica.com.pa/rss.xml",
|
|
"https://www.panamaamerica.com.pa/rss.xml",
|
|
"https://noticiassin.com/feed/",
|
|
"https://elcapitalfinanciero.com/feed/",
|
|
],
|
|
canada: [
|
|
"https://www.cbc.ca/cmlink/rss-topstories",
|
|
"https://calgaryherald.com/feed",
|
|
"https://ottawacitizen.com/feed",
|
|
"https://www.montrealgazette.com/feed",
|
|
],
|
|
singapore: [
|
|
"https://www.straitstimes.com/news/singapore/rss.xml",
|
|
"https://www.channelnewsasia.com/rssfeeds/8395986",
|
|
],
|
|
uk: [
|
|
"http://feeds.bbci.co.uk/news/rss.xml",
|
|
"https://www.theguardian.com/uk/rss",
|
|
],
|
|
japan: [
|
|
"https://www3.nhk.or.jp/nhkworld/en/news/feeds/",
|
|
"https://news.livedoor.com/topics/rss/int.xml",
|
|
],
|
|
netherlands: ["https://www.dutchnews.nl/feed/", "https://www.nrc.nl/rss/"],
|
|
};
|
|
|
|
/**
|
|
* Fetches news articles based on a specified source.
|
|
*
|
|
* The source can be:
|
|
* 1. The string "australia": Fetches news from Australian sources via NewsAPI,
|
|
* handled by the `fetchAustraliaNews` function.
|
|
* 2. A lowercase country code (e.g., "usa", "canada"): Fetches news from a predefined
|
|
* list of RSS feeds for that country, as specified in `rssFeedsByCountry`.
|
|
* 3. A direct RSS feed URL (starting with "http"): Fetches news directly from this URL.
|
|
*
|
|
* The fetched articles are then sent back to the caller using the `sendResponse` callback.
|
|
*
|
|
* @param {string} source The news source identifier. This can be "australia", a
|
|
* lowercase country code, or a direct RSS feed URL.
|
|
* @param {any} sendResponse A callback function (typically from a browser extension
|
|
* message listener, like `chrome.runtime.onMessage`)
|
|
* used to send the fetched news data back to the caller.
|
|
* It's called with an object like `{ news: { articles: [...] } }`.
|
|
*/
|
|
export async function fetchNews(source: string | undefined, sendResponse: any) {
|
|
const normalizedSource = typeof source === "string" && source.trim()
|
|
? source.trim()
|
|
: "australia";
|
|
|
|
if (normalizedSource === "australia") {
|
|
const date = new Date();
|
|
|
|
const from =
|
|
date.getFullYear() +
|
|
"-" +
|
|
(date.getMonth() + 1) +
|
|
"-" +
|
|
(date.getDate() - 5);
|
|
|
|
const url = `https://newsapi.org/v2/everything?domains=abc.net.au&from=${from}&apiKey=17c0da766ba347c89d094449504e3080`;
|
|
fetchAustraliaNews(url, sendResponse);
|
|
|
|
return;
|
|
}
|
|
|
|
const parser = new Parser();
|
|
let feeds: string[];
|
|
console.log("fetchNews", normalizedSource);
|
|
|
|
if (rssFeedsByCountry[normalizedSource.toLowerCase()]) {
|
|
feeds = rssFeedsByCountry[normalizedSource.toLowerCase()];
|
|
} else if (normalizedSource.startsWith("http")) {
|
|
feeds = [normalizedSource];
|
|
} else {
|
|
console.warn("[BetterSEQTA+] Invalid news source, falling back to Australia", normalizedSource);
|
|
return fetchNews("australia", sendResponse);
|
|
}
|
|
|
|
const articlesPromises = feeds.map(async (feedUrl) => {
|
|
try {
|
|
const response = await fetch(feedUrl);
|
|
const feedString = await response.text();
|
|
const feed = await parser.parseString(feedString);
|
|
|
|
return feed.items.map((item) => ({
|
|
title: item.title || "",
|
|
description: item.contentSnippet || "",
|
|
url: item.link || "",
|
|
urlToImage: null,
|
|
}));
|
|
} catch (error) {
|
|
console.error(`Failed to fetch RSS feed: ${feedUrl}`, error);
|
|
return [];
|
|
}
|
|
});
|
|
|
|
const articlesArray = await Promise.all(articlesPromises);
|
|
const articles = articlesArray.flat();
|
|
|
|
sendResponse({ news: { articles } });
|
|
}
|