2
RSS Feed Fetcher Trigger
One script reply has been approved by the moderators Verified

Fetch new items from an RSS Feed

Created by pirmin kalberer631 747 days ago Viewed 18906 times
In Windmill, a trigger script is designed to pull data from an external source and return all the new items since the last run. It operates without resorting to external webhooks and is typically used with schedules and states to compare the current execution to the previous one.
2
Submitted by pirmin kalberer631 Deno
Verified 747 days ago
1
import * as wmill from "https://deno.land/x/windmill@v1.85.0/mod.ts";
2
import { parse } from "https://deno.land/x/xml/mod.ts";
3

4
type Rss = {
5
  url: string;
6
};
7
export async function main(rss_feed: Rss) {
8
  const rss_feed_url = rss_feed.url;
9
  let feedStates = (await wmill.getInternalState()) || {};
10
  const newestItem: Date = new Date(feedStates[rss_feed_url] || 0);
11

12
  const items = await fetch(rss_feed_url)
13
    .then((response) => response.text())
14
    .then((str) => parse(str))
15
    .then((feed) => {
16
      let items = [];
17
      if (feed["rss"]) {
18
        items = rss2_items(feed);
19
      } else if (feed["feed"]) {
20
        items = atom_items(feed);
21
      }
22
      const new_items = items.filter((item) => item.pubDate > newestItem);
23
      return new_items;
24
    });
25

26
  if (items.length > 0) {
27
    let newState = (await wmill.getInternalState()) || {};
28
    const dates = items.map((item) => item.pubDate);
29
    newState[rss_feed_url] = new Date(Math.max(...dates));
30
    await wmill.setInternalState(newState);
31
  }
32

33
  return items.reverse();
34
}
35

36
function rss2_items(feed) {
37
  var items = feed["rss"]["channel"]["item"] || [];
38
  if (items.length === "undefined") {
39
    // Single entry
40
    items = [items];
41
  }
42
  return items.map((item) => ({
43
    title: item.title,
44
    link: item.link,
45
    pubDate: new Date(item.pubDate),
46
  }));
47
}
48

49
function atom_items(feed) {
50
  var items = feed["feed"]["entry"] || [];
51
  if (items.length === "undefined") {
52
    // Single entry
53
    items = [items];
54
  }
55
  return items.map((item) => ({
56
    title: typeof item.title === "string" ? item.title : item.title["#text"],
57
    link:
58
      item.link instanceof Array ? item.link[0]["@href"] : item.link["@href"],
59
    pubDate: new Date(item.updated),
60
  }));
61
}
62

Other submissions