71 lines
2.4 KiB
JavaScript
71 lines
2.4 KiB
JavaScript
/**
|
|
* Proxy für newsdata.io API.
|
|
* Endpoint: https://newsdata.io/api/1/news?apikey=...&language=...&category=...
|
|
* Pagination: counter = wievieltes Widget dieser Art (0 = erste Seite, 1 = zweite, …), damit News nicht doppelt gezeigt werden.
|
|
*/
|
|
|
|
const NEWS_BASE = 'https://newsdata.io/api/1/news';
|
|
|
|
/**
|
|
* @param {object} options
|
|
* @param {number} options.counter - 0 = erste Seite, 1 = zweite, … (für Pagination/nextPage)
|
|
* @param {string} [options.language] - z. B. de, en
|
|
* @param {string} [options.category] - z. B. top, technology
|
|
* @returns {Promise<{ results: Array, nextPage: string|null }>}
|
|
*/
|
|
async function fetchNewsPage({ counter, language = 'de', category = 'top', nextPageToken = null }) {
|
|
const apiKey = process.env.NEWSDATA_IO_API_KEY;
|
|
if (!apiKey || !apiKey.trim()) {
|
|
throw new Error('NEWSDATA_IO_API_KEY is not set in .env');
|
|
}
|
|
const params = new URLSearchParams();
|
|
params.set('apikey', apiKey.trim());
|
|
params.set('language', String(language));
|
|
params.set('category', String(category));
|
|
if (nextPageToken) params.set('page', nextPageToken);
|
|
|
|
const url = `${NEWS_BASE}?${params.toString()}`;
|
|
const res = await fetch(url);
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
throw new Error(`newsdata.io: ${res.status} ${text.slice(0, 200)}`);
|
|
}
|
|
const data = await res.json();
|
|
return {
|
|
results: data.results ?? [],
|
|
nextPage: data.nextPage ?? null
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Liefert die Seite für das „counter.“-te Widget (0 = erste Seite, 1 = zweite, …).
|
|
* Ruft die API ggf. mehrfach auf (nextPage), damit jede Widget-Instanz andere Artikel bekommt.
|
|
*
|
|
* @param {object} options
|
|
* @param {number} options.counter
|
|
* @param {string} [options.language]
|
|
* @param {string} [options.category]
|
|
* @returns {Promise<{ results: Array, nextPage: string|null }>}
|
|
*/
|
|
async function getNews({ counter = 0, language = 'de', category = 'top' }) {
|
|
let nextPageToken = null;
|
|
let lastResult = { results: [], nextPage: null };
|
|
|
|
for (let i = 0; i <= counter; i++) {
|
|
lastResult = await fetchNewsPage({
|
|
counter: i,
|
|
language,
|
|
category,
|
|
nextPageToken: nextPageToken || undefined
|
|
});
|
|
nextPageToken = lastResult.nextPage;
|
|
if (!nextPageToken && i < counter) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return lastResult;
|
|
}
|
|
|
|
export default { getNews };
|