Skip to content

Commit

Permalink
Add collection rss
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-sherman committed Aug 27, 2024
1 parent 4965900 commit 356ae78
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 1 deletion.
5 changes: 4 additions & 1 deletion packages/atproto-browser/app/at/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ export default async function AtPage({
return (
<div>
<h1>
{handle}&apos;s {uri.collection} records
{handle}&apos;s {uri.collection} records{" "}
<Link href={`/collection-rss?u=${uri.toString()}`} title="RSS feed">
🛜
</Link>
</h1>
<ul>
<SWRConfig
Expand Down
70 changes: 70 additions & 0 deletions packages/atproto-browser/app/collection-rss/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { listRecords } from "@/lib/atproto";
import { resolveIdentity } from "@/lib/atproto-server";
import { getHandle, getPds } from "@atproto/identity";
import { AtUri } from "@atproto/syntax";

export const revalidate = 60;

const ORIGIN = "https://atproto-browser.vercel.app";

export async function GET(request: Request) {
const uri = new AtUri(new URL(request.url).searchParams.get("u")!);
if (!uri.origin || uri.rkey) {
return new Response("Invalid collection URI", { status: 400 });
}
const identityResult = await resolveIdentity(uri.host);
if (!identityResult.success) {
return new Response(identityResult.error, { status: 400 });
}

const didDoc = identityResult.identity;
const pds = getPds(didDoc);
if (!pds) {
return new Response(`No PDS found for ${didDoc.id}`, { status: 400 });
}
const handle = getHandle(didDoc);
if (!handle) {
return new Response(`No handle found for ${didDoc.id}`, { status: 400 });
}

const { records } = await listRecords(pds, didDoc.id, uri.collection);

const rss = `
<rss version="2.0">
<channel>
<title>@${handle}'s ${uri.collection} atproto records</title>
<link>${ORIGIN}/collection-rss?u=${uri.toString()}</link>
<description>Collection ${uri.collection} from ${uri.origin}</description>
<language>en-gb</language>
<ttl>60</ttl>
${records
.map((record) =>
`
<item>
<title>${cdata(`New ${uri.collection}: ${new AtUri(record.uri).rkey}`)}</title>
<pubDate>${new Intl.DateTimeFormat("fr-CA", {
year: "numeric",
month: "2-digit",
day: "2-digit",
}).format(new Date())}</pubDate>
<link>${ORIGIN}/collection-rss?u=${uri.toString()}</link>
<guid isPermalink="false">${record.cid}</guid>
</item>
`.trim(),
)
.join("\n")}
</channel>
</rss>
`.trim();

return new Response(rss, {
headers: {
"Content-Type": "application/xml",
"Content-Length": String(new TextEncoder().encode(rss).length),
},
});
}

function cdata(s: string) {
return `<![CDATA[${s}]]>`;
}

0 comments on commit 356ae78

Please sign in to comment.