Polls the Vulkan specification repository for specification updates. If found, sends an email and makes a post on /r/vulkan.

Runs every 15 min
Fork
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
import { fetch } from "https://esm.town/v/std/fetch";
import { set } from "https://esm.town/v/std/set?v=11";
import { getRedditAccessToken } from "https://esm.town/v/tambre/getRedditAccessToken";
import { email } from "https://esm.town/v/std/email?v=9";
let { lastVulkanRSSFeedTime } = await import("https://esm.town/v/tambre/lastVulkanRSSFeedTime");
import { parseXML } from "https://esm.town/v/stevekrouse/parseXML?v=1";
export async function pollVulkanRSSFeed({ lastRunAt }: Interval) {
const githubProject = "https://github.com/KhronosGroup/Vulkan-Docs";
const response = await fetch(`${githubProject}/commits.atom`);
const feed =
(await parseXML(await response.text())).feed;
const entries = feed.entry.filter((entry) =>
new Date(lastVulkanRSSFeedTime) < new Date(entry.updated)
);
for (const entry of entries) {
const titles = entry.title.match(/Vulkan \d+\.\d+\.\d+ spec update/);
if (!titles || !titles.length) {
continue;
}
const title = titles[0];
const url = `${githubProject}/commit/${entry.id.match(/Commit\/(.+)/)[1]}`;
await email({
html: `<a href="${url}">Vulkan-Docs commit</a>\n\n${entry.content}`,
subject: title,
});
const formData = new URLSearchParams();
formData.append("kind", "link");
formData.append("sr", "vulkan");
formData.append("title", title);
formData.append("url", url);
formData.append("send_replies", "true");
const result = await fetch("https://oauth.reddit.com/api/submit", {
method: "POST",
headers: {
"Authorization": `Bearer ${await getRedditAccessToken()}`,
"Content-Type": "application/x-www-form-urlencoded",
},
body: formData.toString(),
});
console.info(`${result.status}: ${await result.text()}`);
lastVulkanRSSFeedTime = new Date(entry.updated).toISOString();
}
await set(
"lastVulkanRSSFeedTime",
lastVulkanRSSFeedTime,
);
return entries;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import process from "node:process";
import { postToMastodon } from "https://esm.town/v/sebdd/postToMastodon";
import { newRSSItems } from "https://esm.town/v/stevekrouse/newRSSItems?v=6";
export async function tootLatestPosts({ lastRunAt }: Interval) {
return Promise.all(
(await newRSSItems({
url: "https://sebastiandedeyne.com/index.xml",
lastRunAt,
}))
.slice(0, 2)
.map((item) =>
postToMastodon(
"https://mastodon.social/api/v1",
process.env.mastodonAccessToken,
`${item.title.charAt(0) === "↗" ? "🔗" : "✍️"} ${
item.title.replace("↗ ", "")
} ${item.link}`,
)
),
);
}
1
2
3
4
5
6
import { newRSSItems } from "https://esm.town/v/stevekrouse/newRSSItems?v=6";
export const RSSFeed = newRSSItems({
url: "https://inkandswitch.com/index.xml",
lastRunAt: "January 01, 2020",
});
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
import { email } from "https://esm.town/v/std/email?v=11";
import { fetchRSS } from "https://esm.town/v/stevekrouse/fetchRSS";
import { newRSSItems } from "https://esm.town/v/stevekrouse/newRSSItems?v=6";
import { parseXML } from "https://esm.town/v/stevekrouse/parseXML";
export default async function(interval: Interval) {
// const lastRunAt = new Date(Date.now() - 1000 * 60 * 60 * 24 * 30 * 3);
const lastRunAt = interval.lastRunAt;
const response = await fetch("https://sive.rs/en.atom");
const xml = await response.text();
const data = await parseXML(xml);
const entries: { id: string; title: string; content: string; updated: string }[] = data.feed.entry;
const newItems = entries.filter(entry => {
return new Date(entry.updated) > new Date(lastRunAt);
});
console.log("New Items", lastRunAt, newItems);
const html = newItems.map(({ id, title, content, updated }) => {
const date = new Date(updated).toLocaleDateString();
return `<h2><a href="${id}">${title}</a> - ${date}</h2>${content}`;
}).join("\n");
if (newItems.length === 0) return;
email({ subject: `Sive.rs: ${newItems[0].title}`, html: html });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import { newRSSItems } from "https://esm.town/v/stevekrouse/newRSSItems?v=6";
export let postWebhook1 = async (req, res) => {
const a = await newRSSItems({
url: "https://elliot.website/editor/feed.rss",
lastRunAt: new Date("Mon, 31 Oct 2021 00:00:00 +0000"),
});
res.send(`
<h1>My latest RSS</h1>
<ul>${a
.map(
({ title, link, description, pubDate }) => `
<li>
<a href="${link}">
<strong>${title}</strong><small>${pubDate}</small><br>
${description}
</a>
</li>
`
)
.join("")}
</ul>`);
};
1
2
3
4
5
6
import { newRSSItems } from "https://esm.town/v/stevekrouse/newRSSItems?v=6";
export const RSSFeed = newRSSItems({
url: "https://inkandswitch.com/index.xml",
lastRunAt: "January 01, 2020",
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { newRSSItems } from "https://esm.town/v/stevekrouse/newRSSItems?v=6";
import { rssFeeds } from "https://esm.town/v/dosirak/rssFeeds";
export async function pollRSSFeeds({ lastRunAt }) {
return Promise.all(
Object.entries(rssFeeds).map(async ([name, url]) => {
let items = await newRSSItems({
url,
lastRunAt,
});
if (items.length) console.email(items, `New from ${name} RSS`);
return { name, items };
})
);
}
1
2
3
4
5
6
import { newRSSItems } from "https://esm.town/v/stevekrouse/newRSSItems?v=6";
export const RSSFeed = newRSSItems({
url: "https://inkandswitch.com/index.xml",
lastRunAt: "January 01, 2020",
});
Runs every 1 min
Fork
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { email } from "https://esm.town/v/std/email?v=9";
import { set } from "https://esm.town/v/std/set?v=11";
import { inkAndSwitchRssUrl } from "https://esm.town/v/stevekrouse/inkAndSwitchRssUrl";
import { newRSSItems } from "https://esm.town/v/stevekrouse/newRSSItems";
import { pollRSSInkAndSwitch } from "https://esm.town/v/stevekrouse/pollRSSInkAndSwitch";
export async function pollRSSFeeds2() {
let items = await newRSSItems({
url: inkAndSwitchRssUrl,
lastRunAt: pollRSSInkAndSwitch,
});
if (items.length)
await email({
text: JSON.stringify(items, null, 2),
subject: `New RSS Item`,
});
return set("pollRSSInkAndSwitch", Date.now());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { msDay } from "https://esm.town/v/stevekrouse/msDay?v=1";
import { newRSSItems } from "https://esm.town/v/stevekrouse/newRSSItems?v=6";
export async function getMcgillEvents() {
const url =
"https://www.alumni.mcgill.ca/aoc/events-travel/registration/regwizEventsList.php?location=050%3AMA&school=&dateMonth=&title=&doSearch=1";
const items = await newRSSItems({
url: url,
lastRunAt: Date.now() - 60 * msDay,
});
if (items.length) {
console.email(items, "New from Mcgill Alumni Events");
}
}
1
2
3
4
5
6
import { newRSSItems } from "https://esm.town/v/stevekrouse/newRSSItems?v=6";
export const RSSFeed = newRSSItems({
url: "https://inkandswitch.com/index.xml",
lastRunAt: "January 01, 2020",
});
1
2
3
4
5
6
7
8
9
10
11
12
13
import { newRSSItems } from "https://esm.town/v/stevekrouse/newRSSItems?v=6";
import { rssFeeds } from "https://esm.town/v/ianv/rssFeeds";
export async function pollRSSFeeds({ lastRunAt }) {
return Object.entries(rssFeeds).map(async ([name, url]) => {
let items = await newRSSItems({
url,
lastRunAt,
});
if (items.length) console.email(items, `New from ${name} RSS`);
return { name, items };
});
}
1
2
3
4
5
6
import { newRSSItems } from "https://esm.town/v/stevekrouse/newRSSItems?v=6";
export const RSSFeed = newRSSItems({
url: "https://inkandswitch.com/index.xml",
lastRunAt: "January 01, 2020",
});

Auto-tooting anniversary posts from https://crimenesdeodio.info/ to remember hate crimes in Spain between 1990-2020.

Runs every 1 hrs
Fork
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { postToMastodon } from "https://esm.town/v/sebdd/postToMastodon";
import { newRSSItems } from "https://esm.town/v/stevekrouse/newRSSItems?v=6";
export async function tootLatestPosts({ lastRunAt }: Interval) {
return Promise.all(
(await newRSSItems({
url: "https://crimenesdeodio.info/es/rss-feed-yearly",
lastRunAt,
}))
.slice(0, 2)
.map((item) =>
postToMastodon(
"https://floss.social/api/v1",
Deno.env.get("mastodonAccessToken"),
`${item.title.charAt(0) === "↗" ? "🔗" : "✍️"} ${item.title.replace("↗ ", "")} ${item.link}`,
)
),
);
}

Poll RSS feeds

This val periodically polls specified RSS feeds and send the author an email with new items. It checks each feed defined in rssFeeds for new content since the last run and sends an email with the details of the new items.

Usage

  1. Fork @stevekrouse/rssFeeds and update it with your desired RSS feeds;
  2. Fork this val and replace the https://esm.town/v/stevekrouse/rssFeeds import with your newly forked val;
  3. Enjoy RSS updates on your email!
Runs every 1 days
Fork
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { email } from "https://esm.town/v/std/email?v=9";
import { newRSSItems } from "https://esm.town/v/stevekrouse/newRSSItems";
import { rssFeeds } from "https://esm.town/v/stevekrouse/rssFeeds";
export async function pollRSSFeeds({ lastRunAt }: Interval) {
return Promise.all(
Object.entries(rssFeeds).map(async ([name, url]) => {
let items = await newRSSItems({
url,
lastRunAt,
});
if (items.length)
await email({
text: JSON.stringify(items, null, 2),
subject: `New from ${name} RSS`,
});
return { name, items };
}),
);
}