|
@@ -3,6 +3,7 @@ import { getGrowiVersion } from '~/utils/growi-version';
|
|
|
import loggerFactory from '~/utils/logger';
|
|
import loggerFactory from '~/utils/logger';
|
|
|
|
|
|
|
|
import type { INewsItemInput } from '../../interfaces/news-item';
|
|
import type { INewsItemInput } from '../../interfaces/news-item';
|
|
|
|
|
+import { type FeedItem, parseFeedJson } from './feed-parser';
|
|
|
import { NewsService } from './news-service';
|
|
import { NewsService } from './news-service';
|
|
|
|
|
|
|
|
const logger = loggerFactory('growi:feature:news:cron');
|
|
const logger = loggerFactory('growi:feature:news:cron');
|
|
@@ -20,25 +21,6 @@ const FETCH_TIMEOUT_MS = 10_000;
|
|
|
*/
|
|
*/
|
|
|
const MAX_RESPONSE_SIZE_BYTES = 5 * 1024 * 1024;
|
|
const MAX_RESPONSE_SIZE_BYTES = 5 * 1024 * 1024;
|
|
|
|
|
|
|
|
-interface FeedItem {
|
|
|
|
|
- id: string;
|
|
|
|
|
- type?: string;
|
|
|
|
|
- emoji?: string;
|
|
|
|
|
- title: Record<string, string>;
|
|
|
|
|
- body?: Record<string, string>;
|
|
|
|
|
- url?: string;
|
|
|
|
|
- publishedAt: string;
|
|
|
|
|
- conditions?: {
|
|
|
|
|
- targetRoles?: string[];
|
|
|
|
|
- growiVersionRegExps?: string[];
|
|
|
|
|
- };
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-interface FeedJson {
|
|
|
|
|
- version: string;
|
|
|
|
|
- items: FeedItem[];
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
/**
|
|
/**
|
|
|
* Check if the given URL is allowed for fetching
|
|
* Check if the given URL is allowed for fetching
|
|
|
*/
|
|
*/
|
|
@@ -102,7 +84,7 @@ export class NewsCronService extends CronService {
|
|
|
// Random sleep to distribute requests across multiple GROWI instances
|
|
// Random sleep to distribute requests across multiple GROWI instances
|
|
|
await randomSleep(MAX_RANDOM_SLEEP_MS);
|
|
await randomSleep(MAX_RANDOM_SLEEP_MS);
|
|
|
|
|
|
|
|
- let feedJson: FeedJson;
|
|
|
|
|
|
|
+ let rawJson: unknown;
|
|
|
try {
|
|
try {
|
|
|
const response = await fetch(feedUrl, {
|
|
const response = await fetch(feedUrl, {
|
|
|
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
|
|
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
|
|
@@ -121,12 +103,17 @@ export class NewsCronService extends CronService {
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- feedJson = JSON.parse(text) as FeedJson;
|
|
|
|
|
|
|
+ rawJson = JSON.parse(text);
|
|
|
} catch (err) {
|
|
} catch (err) {
|
|
|
logger.error('Error fetching news feed, keeping existing data', err);
|
|
logger.error('Error fetching news feed, keeping existing data', err);
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ const feedJson = parseFeedJson(rawJson);
|
|
|
|
|
+ if (feedJson == null) {
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
const currentVersion = getGrowiVersion();
|
|
const currentVersion = getGrowiVersion();
|
|
|
const filteredItems = feedJson.items.filter((item) =>
|
|
const filteredItems = feedJson.items.filter((item) =>
|
|
|
matchesGrowiVersion(item, currentVersion),
|
|
matchesGrowiVersion(item, currentVersion),
|