aboutsummaryrefslogtreecommitdiffstats
path: root/packages/api/routes
diff options
context:
space:
mode:
authorMohamed Bassem <me@mbassem.com>2025-05-31 18:46:04 +0100
committerGitHub <noreply@github.com>2025-05-31 18:46:04 +0100
commit9695bba2e993b48ae333da622fa459dbaacb9349 (patch)
treec6bffbcdd73151671343f27012e82bea5a05ab6b /packages/api/routes
parentb218118b84291de4a9c1cd400dc58afab7054b78 (diff)
downloadkarakeep-9695bba2e993b48ae333da622fa459dbaacb9349.tar.zst
feat: Generate RSS feeds from lists (#1507)
* refactor: Move bookmark utils from shared-react to shared * Expose RSS feeds for lists * Add e2e tests * Slightly improve the look of the share dialog * allow specifying a limit in the rss endpoint
Diffstat (limited to 'packages/api/routes')
-rw-r--r--packages/api/routes/rss.ts51
1 files changed, 51 insertions, 0 deletions
diff --git a/packages/api/routes/rss.ts b/packages/api/routes/rss.ts
new file mode 100644
index 00000000..81c9756c
--- /dev/null
+++ b/packages/api/routes/rss.ts
@@ -0,0 +1,51 @@
+import { zValidator } from "@hono/zod-validator";
+import { Hono } from "hono";
+import { z } from "zod";
+
+import serverConfig from "@karakeep/shared/config";
+import { MAX_NUM_BOOKMARKS_PER_PAGE } from "@karakeep/shared/types/bookmarks";
+import { List } from "@karakeep/trpc/models/lists";
+
+import { unauthedMiddleware } from "../middlewares/auth";
+import { toRSS } from "../utils/rss";
+
+const app = new Hono().get(
+ "/lists/:listId",
+ zValidator(
+ "query",
+ z.object({
+ token: z.string().min(1),
+ limit: z.coerce
+ .number()
+ .min(1)
+ .max(MAX_NUM_BOOKMARKS_PER_PAGE)
+ .optional(),
+ }),
+ ),
+ unauthedMiddleware,
+ async (c) => {
+ const listId = c.req.param("listId");
+ const searchParams = c.req.valid("query");
+ const token = searchParams.token;
+
+ const res = await List.getForRss(c.var.ctx, listId, token, {
+ limit: searchParams.limit ?? 20,
+ });
+ const list = res.list;
+
+ const rssFeed = toRSS(
+ {
+ title: `Bookmarks from ${list.icon} ${list.name}`,
+ feedUrl: `${serverConfig.publicApiUrl}/v1/rss/lists/${listId}`,
+ siteUrl: `${serverConfig.publicUrl}/dashboard/lists/${listId}`,
+ description: list.description ?? undefined,
+ },
+ res.bookmarks,
+ );
+
+ c.header("Content-Type", "application/rss+xml");
+ return c.body(rssFeed);
+ },
+);
+
+export default app;