/
index.ts
55 lines (51 loc) 路 2.03 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import { Route } from '@/types';
import cache from '@/utils/cache';
import got from '@/utils/got';
import parser from '@/utils/rss-parser';
import { load } from 'cheerio';
import { isValidHost } from '@/utils/valid-host';
import InvalidParameterError from '@/errors/types/invalid-parameter';
export const route: Route = {
path: '/news/en/:category?',
name: 'Unknown',
maintainers: [],
handler,
};
async function handler(ctx) {
const region = ctx.req.param('region') === 'en' ? '' : ctx.req.param('region').toLowerCase();
if (!isValidHost(region) && region !== '') {
throw new InvalidParameterError('Invalid region');
}
const category = ctx.req.param('category') ? ctx.req.param('category').toLowerCase() : '';
const rssUrl = `https://${region ? `${region}.` : ''}news.yahoo.com/rss/${category}`;
const feed = await parser.parseURL(rssUrl);
const filteredItems = feed.items.filter((item) => !item.link.includes('promotions') && new URL(item.link).hostname.match(/.*\.yahoo\.com$/));
const items = await Promise.all(
filteredItems.map((item) =>
cache.tryGet(item.link, async () => {
const response = await got({
method: 'get',
url: item.link,
});
const $ = load(response.data);
const author = `${$('span.caas-author-byline-collapse').text()} @${$('span.caas-attr-provider').text()}`;
$('.caas-content-byline-wrapper, .caas-xray-wrapper, .caas-header, .caas-readmore').remove();
const description = $('.caas-content-wrapper').html();
const single = {
title: item.title,
description,
author,
pubDate: item.pubDate,
link: item.link,
};
return single;
})
)
);
return {
title: feed.title,
link: feed.link,
description: feed.description,
item: items,
};
}