Files
Mebbling/app/rss.xml/route.ts
T

9 lines
1.3 KiB
TypeScript

import { db } from "@/lib/db";
const escapeXml = (value: string) => value.replace(/[<>&'\"]/g, (char) => ({ "<": "&lt;", ">": "&gt;", "&": "&amp;", "'": "&apos;", '"': "&quot;" }[char] || char));
export async function GET() {
const origin = (process.env.NEXT_PUBLIC_APP_URL || "http://localhost:8088").replace(/\/$/, ""); const posts = db.prepare("SELECT p.id,p.content,COALESCE(p.remote_created_at,p.created_at) AS published_at,u.username FROM posts p JOIN users u ON u.id=p.author_id WHERE p.visibility='PUBLIC' AND p.hidden=0 ORDER BY COALESCE(p.remote_created_at,p.created_at) DESC LIMIT 50").all() as { id: number; content: string; published_at: string; username: string }[];
const items = posts.map((post) => `<item><title>${escapeXml(`@${post.username} 的貼文`)}</title><link>${origin}/posts/${post.id}</link><guid>${origin}/posts/${post.id}</guid><description>${escapeXml(post.content.slice(0, 500))}</description><pubDate>${new Date(post.published_at).toUTCString()}</pubDate></item>`).join("");
return new Response(`<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>Mebbling</title><link>${origin}</link><description>公開 Memos Hub</description>${items}</channel></rss>`, { headers: { "Content-Type": "application/rss+xml; charset=utf-8", "Cache-Control": "public, max-age=300" } });
}