a tool for shared writing and social publishing

add rss feed to pubs

+91
+58
app/lish/[did]/[publication]/rss/route.ts
··· 1 + import { AtUri } from "@atproto/syntax"; 2 + import { get_publication_data } from "app/api/rpc/[command]/get_publication_data"; 3 + import { Feed } from "feed"; 4 + import fs from "fs/promises"; 5 + import { PubLeafletDocument, PubLeafletPublication } from "lexicons/api"; 6 + import { NextRequest, NextResponse } from "next/server"; 7 + import { supabaseServerClient } from "supabase/serverClient"; 8 + 9 + export async function GET( 10 + req: Request, 11 + props: { 12 + params: Promise<{ publication: string; did: string }>; 13 + }, 14 + ) { 15 + let params = await props.params; 16 + let { result: publication } = await get_publication_data.handler( 17 + { 18 + did: params.did, 19 + publication_name: decodeURIComponent(params.publication), 20 + }, 21 + { supabase: supabaseServerClient }, 22 + ); 23 + 24 + let pubRecord = publication?.record as PubLeafletPublication.Record; 25 + if (!publication || !pubRecord) 26 + return new NextResponse(null, { status: 404 }); 27 + 28 + const feed = new Feed({ 29 + title: pubRecord.name, 30 + description: pubRecord.description, 31 + id: `https://${pubRecord.base_path}`, 32 + link: `https://${pubRecord.base_path}`, 33 + language: "en", // optional, used only in RSS 2.0, possible values: http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes 34 + copyright: "", 35 + feedLinks: { 36 + rss: `https://${pubRecord.base_path}/rss`, 37 + }, 38 + }); 39 + 40 + publication?.documents_in_publications.forEach((doc) => { 41 + if (!doc.documents) return; 42 + let record = doc.documents?.data as PubLeafletDocument.Record; 43 + let rkey = new AtUri(doc.documents?.uri).rkey; 44 + if (!record) return; 45 + feed.addItem({ 46 + title: record.title, 47 + description: record.description, 48 + date: record.publishedAt ? new Date(record.publishedAt) : new Date(), 49 + id: `https://${pubRecord.base_path}/${rkey}`, 50 + link: `https://${pubRecord.base_path}/${rkey}`, 51 + }); 52 + }); 53 + return new Response(feed.rss2(), { 54 + headers: { 55 + "Content-Type": "application/rss+xml", 56 + }, 57 + }); 58 + }
+32
package-lock.json
··· 36 36 "base64-js": "^1.5.1", 37 37 "colorjs.io": "^0.5.2", 38 38 "drizzle-orm": "^0.30.10", 39 + "feed": "^5.0.1", 39 40 "fractional-indexing": "^3.2.0", 40 41 "linkifyjs": "^4.2.0", 41 42 "multiformats": "^13.3.2", ··· 9221 9222 "reusify": "^1.0.4" 9222 9223 } 9223 9224 }, 9225 + "node_modules/feed": { 9226 + "version": "5.0.1", 9227 + "resolved": "https://registry.npmjs.org/feed/-/feed-5.0.1.tgz", 9228 + "integrity": "sha512-kOveKLHucVZ6RI91bdWAts9O0L1N2mGzRGVCDQPRnHh4HmgqLdN66Cp/5dMeJZGn/qnBslWliwX37FEBq8DCIA==", 9229 + "license": "MIT", 9230 + "dependencies": { 9231 + "xml-js": "^1.6.11" 9232 + }, 9233 + "engines": { 9234 + "node": ">=20", 9235 + "pnpm": ">=10" 9236 + } 9237 + }, 9224 9238 "node_modules/fetch-blob": { 9225 9239 "version": "3.2.0", 9226 9240 "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", ··· 14640 14654 "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 14641 14655 "license": "MIT" 14642 14656 }, 14657 + "node_modules/sax": { 14658 + "version": "1.4.1", 14659 + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", 14660 + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", 14661 + "license": "ISC" 14662 + }, 14643 14663 "node_modules/scheduler": { 14644 14664 "version": "0.26.0", 14645 14665 "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", ··· 16990 17010 "utf-8-validate": { 16991 17011 "optional": true 16992 17012 } 17013 + } 17014 + }, 17015 + "node_modules/xml-js": { 17016 + "version": "1.6.11", 17017 + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", 17018 + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", 17019 + "license": "MIT", 17020 + "dependencies": { 17021 + "sax": "^1.2.4" 17022 + }, 17023 + "bin": { 17024 + "xml-js": "bin/cli.js" 16993 17025 } 16994 17026 }, 16995 17027 "node_modules/xmlbuilder": {
+1
package.json
··· 43 43 "base64-js": "^1.5.1", 44 44 "colorjs.io": "^0.5.2", 45 45 "drizzle-orm": "^0.30.10", 46 + "feed": "^5.0.1", 46 47 "fractional-indexing": "^3.2.0", 47 48 "linkifyjs": "^4.2.0", 48 49 "multiformats": "^13.3.2",