import { notifications, type Notification, } from "$lib/Data/AniList/notifications"; import { siteUrl } from "$lib/Utility/appOrigin"; import root from "$lib/Utility/root"; const htmlEncode = (input: string) => { return input.replace( /[\u00A0-\u9999<>&]/g, (i) => "&#" + i.charCodeAt(0) + ";", ); }; const render = ( posts: Notification[] = [], ) => ` AniList Notifications • due.moe ${siteUrl("/")} Instantly view your AniList notifications via RSS! ${new Date().toUTCString()} ${new Date().toUTCString()} en-US ${siteUrl("/favicon-196x196.png")} ${posts .filter((notification: Notification) => notification.type !== undefined) .map((notification: Notification) => { let title = `${notification.user.name}${notification.context}`; let link = `https://anilist.co/user/${notification.user.name}`; const prettyType = notification.type .toString() .replace(/_/g, " ") .toLowerCase() .replace(/\w\S*/g, (text) => { return text.charAt(0).toUpperCase() + text.substr(1).toLowerCase(); }); try { if ( !["FOLLOWING", "ACTIVITY_MESSAGE"].includes( notification.type.toString(), ) && !notification.type.toString().includes("THREAD") ) { link = `https://anilist.co/activity/${notification.activity.id}`; } else if (notification.type.toString().includes("THREAD")) { title += `${notification.thread.title}`; link = `https://anilist.co/forum/thread/${notification.thread.id}`; } } catch { return ""; } return ` ${notification.id} ${htmlEncode(title)} ${link} ${notification.user.name} ${prettyType} ${new Date(notification.createdAt * 1000).toUTCString()} `; }) .join("")} `; export const GET = async ({ url }) => { let token = url.searchParams.get("token"); const refresh = url.searchParams.get("refresh"); let notification = await notifications(token || ""); if (notification === null) { token = ( await (await fetch(root(`/api/oauth/refresh?token=${refresh}`))).json() )["access_token"]; notification = await notifications(token as string); } return new Response(token ? render(notification || []) : render(), { headers: { "Cache-Control": `max-age=0`, "Content-Type": "application/xml", }, }); };