new-manga/src/pages/rss/[feedId].xml.ts
2025-02-04 19:10:22 -07:00

76 lines
No EOL
2.2 KiB
TypeScript

import { Feed } from 'feed';
import { getChaptersForSlugs, isValidLanguage } from "../../lib/api";
import { getFeedMapping, warmChapterCache } from "../../lib/db";
import type { APIRoute } from "astro";
export const GET: APIRoute = async ({ params, request }) => {
const feedId = params.feedId?.replace('.xml', '');
if (!feedId) {
return new Response("Feed ID not provided", { status: 400 });
}
const mapping = await getFeedMapping(feedId);
if (!mapping) {
return new Response("Feed not found", { status: 404 });
}
const { slugs, lang } = mapping;
if (!isValidLanguage(lang)) {
return new Response("Invalid language", { status: 400 });
}
await warmChapterCache(slugs, lang);
const chapters = await getChaptersForSlugs(slugs, lang);
if (chapters.length === 0) {
return new Response("No chapters found for the provided comics", { status: 404 });
}
const siteUrl = new URL(request.url).origin;
const feedUrl = new URL(request.url).href;
const feed = new Feed({
title: `ComicK - Custom Feed (${lang.toUpperCase()})`,
description: `Custom RSS feed for selected comics: ${slugs.join(', ')}`,
id: feedUrl,
link: siteUrl,
feedLinks: {
rss2: feedUrl
},
language: lang,
copyright: "All rights reserved",
updated: new Date(),
generator: 'ComicK RSS Generator',
});
chapters.forEach((chapter) => {
const chapterUrl = `https://comick.io/comic/${chapter.md_comics.slug}`;
feed.addItem({
title: `${chapter.md_comics.title} - Chapter ${chapter.chap}`,
id: `${chapter.md_comics.slug}-${chapter.chap}`,
link: chapterUrl,
description: `
<div>
${
chapter.md_comics.md_covers?.[0]
? `<img src="https://meo.comick.pictures/${chapter.md_comics.md_covers[0].b2key}"
alt="Cover" style="max-width: 300px; margin-bottom: 1rem;" />`
: ""
}
<p>New chapter available: Chapter ${chapter.chap}</p>
</div>
`,
date: new Date(chapter.updated_at),
});
});
return new Response(feed.rss2(), {
headers: {
'Content-Type': 'application/xml; charset=utf-8',
},
});
};