Avatar

jordan

3 public vals
Joined February 2, 2023

Bluesky RSS bot

This is a bot that polls an RSS feed for a new item every hour and posts it to Bluesky.

It's split into three parts:

  1. bsky_rss_poll
    • This function runs every hour and polls the provided RSS feed, turns it into XML and runs the check. If there is a new post, it tell rss_to_bskyto post a link (and the title) to Bluesky
  2. latest_rss
    • This is a stored object that keeps the latest object for the poll to test against
  3. rss_to_bsky
    • This function turns the text post into a rich text post and posts it to Bluesky
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
import { fetch } from "https://esm.town/v/std/fetch";
import { rss_to_bsky } from "https://esm.town/v/jordan/rss_to_bsky";
import { set } from "https://esm.town/v/std/set?v=11";
import { latest_rss as latest_rss2 } from "https://esm.town/v/jordan/latest_rss";
export async function bsky_rss_poll() {
const { parseFeed } = await import("https://deno.land/x/rss/mod.ts");
const res = await fetch("https://v8.dev/blog.atom")
.then(res => res.text())
.then(res => parseFeed(res));
const title = res.entries[0].title.value, url = res.entries[0].id;
const latest_rss = JSON.stringify({ "title": title, "url": url });
if(latest_rss2 !== latest_rss) {
await set("latest_rss", latest_rss);
const post = `${title}
${url} `;
await Promise.all([
rss_to_bsky(post)
]);
}
}
1
2
// set by jordan.bsky_rss_poll at 2023-08-24T17:04:27.928Z
export let latest_rss = "{\"title\":\"Speeding up V8 heap snapshots\",\"url\":\"https://v8.dev/blog/speeding-up-v8-heap-snapshots\"}";
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
import { latest_rss as latest_rss2 } from "https://esm.town/v/jordan/latest_rss";
import process from "node:process";
export async function rss_to_bsky(text) {
import bsky from "npm:@atproto/api";
const { BskyAgent, RichText } = bsky;
const agent = new BskyAgent({ service: "https://bsky.social" });
await agent.login({
identifier: process.env.BLUESKY_USERNAME!,
password: process.env.BLUESKY_PASSWORD!,
});
const post = new RichText({ text: text });
await post.detectFacets(agent);
const postRecord = {
$type: 'app.bsky.feed.post',
text: post.text,
facets: post.facets,
createdAt: new Date().toISOString()
};
const latest_rss = latest_rss2;
if(latest_rss !== undefined) {
await agent.post(postRecord);
}
};
Next