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
56
57
58
59
60
61
import { rss } from "https://esm.town/v/zackoverflow/rss";
type Entry = {
description: {
value: string;
};
links: Array<{
href: string;
}>;
title: {
value: string;
};
published: Date;
};
type RssCacheEntry = {
lastEntry: string | undefined;
};
export const pollRss = async (
rssFeeds: Array<string>,
rssCache: Record<string, RssCacheEntry>,
): Promise<
Array<{
title: string;
url: string;
newEntries: Array<Entry>;
}>
> => {
const promises = rssFeeds.map((url) =>
rss(url).catch((err) =>
console.log(`RSS (${url}) failed`, err)
).then((rssData) => {
const updateDate = new Date(rssData.updateDate);
const cacheValue: RssCacheEntry | undefined = rssCache[url];
const cacheValueEntry = cacheValue?.lastEntry === undefined
? new Date("0000-01-01")
: new Date(cacheValue.lastEntry);
// If is earlier than update date
if ((cacheValueEntry as any) < (updateDate as any)) {
const oldLastEntryDate = cacheValueEntry;
if (!rssCache[url]) {
rssCache[url] = {
lastEntry: (updateDate ?? new Date())
.toISOString(),
};
}
const newEntries = rssData.entries.filter((entry) =>
new Date(entry.published) > oldLastEntryDate
).sort((a, b) =>
(new Date(b.published) as any) - (new Date(a.published) as any)
).slice(0, 15).map((entry) => ({
...entry,
published: new Date(entry.published),
}));
return { title: rssData.title.value, url: url, newEntries };
}
return undefined;
})
);
const newEntries = await Promise.all(promises);
return newEntries.filter((entry) => entry !== undefined);
};
Val Town is a social website to write and deploy JavaScript.
Build APIs and schedule functions from your browser.
Comments
Nobody has commented on this val yet: be the first!
October 23, 2023