import sanitizeHtml from "sanitize-html";
import { request } from "undici";
const MASTODON_HOST = "https://nyan.lol";
const TIMELINE_API = `${MASTODON_HOST}/api/v1/timelines/home?limit=40`;
const VERIFY_API = `${MASTODON_HOST}/api/v1/accounts/verify_credentials`;
export async function getTimeline(token) {
const { body } = await request(TIMELINE_API, {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
});
const json = await body.json();
return json;
}
export async function getUser(token) {
const { body } = await request(VERIFY_API, {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
});
const json = await body.json();
return json;
}
function filter(timeline) {
return timeline.filter(
({ in_reply_to_id, in_reply_to_account_id, reblog, filtered, muted }) => {
return !(
in_reply_to_id ||
in_reply_to_account_id ||
reblog ||
filtered.length > 0 ||
muted
);
},
);
}
function buildHtml({
content,
card,
favourites_count,
media_attachments,
reblogs_count,
replies_count,
}) {
const mediaHtml = media_attachments
.map(({ type, url, description }) => {
if (type === "image") {
return ``;
}
if (type === "video") {
return ``;
}
})
.join("
");
const cardHtml = card
? `
${ card.image ? `` : ""; const statsHtml = `
` : "" }${card.title ? `${card.title}` : ""}
${sanitizedContent}
${mediaHtml}${cardHtml}${statsHtml}`; } function processTimeline(timeline) { const cleanTimeline = filter(timeline); return cleanTimeline.map((status) => { const content = status.content; const summary = sanitizeHtml(content, { allowedTags: [], allowedAttributes: {}, }); const name = status.account.display_name || status.account.acct; const firstImage = status.media_attachments.find( ({ type }) => type === "image", )?.[0]?.url; const content_html = buildHtml(status); return { author: { name, url: status.account.url, avatar: status.account.avatar, }, date_published: status.created_at, date_modified: status.edited_at, external_url: status?.card?.url, id: status.url, image: firstImage, summary, tags: status.tags?.map(({ name }) => name), title: name, url: status.url, content_html, }; }); } export function buildJsonFeed(user, timeline) { const items = processTimeline(timeline); return { version: "https://jsonfeed.org/version/1.1", title: `${user.username}'s Timeline`, description: "A personalized Mastodon feed", home_page_url: user.url, items, }; }