Skip to content

Instantly share code, notes, and snippets.

@jakelazaroff
Last active October 28, 2023 07:41
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jakelazaroff/5256e91395188da72cecbf086723ee6f to your computer and use it in GitHub Desktop.
Save jakelazaroff/5256e91395188da72cecbf086723ee6f to your computer and use it in GitHub Desktop.
Publish the latest post in an RSS feed to an ActivityPub Starter Kit feed
import { XMLParser } from "fast-xml-parser";
import fetch from "node-fetch";
const RSS_URL = "https://jakelazaroff.com/rss.xml";
const ACTIVITYPUB_HOST = "https://shine-thunder-forgery.glitch.me";
const OUTBOX_URL = ACTIVITYPUB_HOST + "/test/outbox";
const CREATE_URL = ACTIVITYPUB_HOST + "/admin/create";
const ADMIN_USERNAME = "jake";
const ADMIN_PASSWORD = "test";
console.log(`Fetching RSS feed from ${RSS_URL}…`);
const rss = await fetch(RSS_URL);
const feed = new XMLParser().parse(await rss.text());
const latest = feed.rss.channel.item[0];
console.log(`Fetching ActivityPub feed from ${OUTBOX_URL}…`);
const outbox = await fetch(OUTBOX_URL);
const posts = await outbox.json();
const post = posts.orderedItems[0];
if (latest.link === post.object?.url) console.log("No new post in feed.");
else {
console.log("Posting to ActivityPub feed…");
const credentials = "Basic " + Buffer.from(ADMIN_USERNAME + ":" + ADMIN_PASSWORD).toString("base64");
const date = new Date(latest.pubDate);
const body = JSON.stringify({
object: {
url: latest.link,
title: latest.title,
summary: latest.description,
content: latest["content:encoded"],
published: date.toISOString()
}
});
const res = await fetch(CREATE_URL, {
method: "POST",
body,
headers: { authorization, "content-type": "application/json" }
});
if (!res.ok) throw new Error(`Got ${res.status} ${res.statusText} when creating post.`);
}
on: [push]
jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: latest
- name: Set up Node
uses: actions/setup-node@v3
with:
node-version: lts/*
cache: "pnpm"
- name: Install site dependencies
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm build
- name: Deploy to Cloudflare Pages
id: pages_deploy
uses: cloudflare/pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: ${{ secrets.CLOUDFLARE_PAGES_PROJECT_NAME }}
directory: build
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
- name: Install script dependencies
run: pnpm install fast-xml-parser node-fetch@2
- name: Publish latest post to ActivityPub
if: ${{ github.ref == format('refs/heads/{0}', github.event.repository.default_branch) }}
run: node ./rss2activitypub.js
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment