From 25d770662a6f31058478be82336b5c26f372b028 Mon Sep 17 00:00:00 2001 From: dylan Date: Thu, 25 Dec 2025 20:54:44 +0000 Subject: [PATCH] added support for both RSS and Atom feeds in getAtomFeedItem and implemented getMastodonPost function to fetch non-reply items --- utils.js | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/utils.js b/utils.js index f5f753b..21f087d 100644 --- a/utils.js +++ b/utils.js @@ -53,9 +53,57 @@ export async function getAtomFeedItem(feedUrl) { const res = await fetch(feedUrl) const data = await res.text() const dom = new JSDOM(data) - const entry = dom.window.document.querySelector('entry') - const title = entry.querySelector('title').textContent - const link = entry.querySelector('link').getAttribute('href') + + // check if it's rss (item) or atom (entry) + let element = dom.window.document.querySelector('entry') + if (!element) { + element = dom.window.document.querySelector('item') + } + + const title = element.querySelector('title').textContent + + // try to get link - atom uses href attribute, rss uses text content + const linkElement = element.querySelector('link') + const link = linkElement.getAttribute('href') || linkElement.textContent.trim() + + const cleanTitle = sanitizeHtml(title, { + allowedTags: [], + allowedAttributes: {}, + })?.trim() + return { text: cleanTitle, url: link } +} + +export async function getMastodonPost(feedUrl) { + const res = await fetch(feedUrl) + const data = await res.text() + const dom = new JSDOM(data) + + // get all items from the rss feed + const items = dom.window.document.querySelectorAll('item') + + // find the first item that isn't a reply (doesn't start with @) + for (const item of items) { + const description = item.querySelector('description')?.textContent || '' + const title = item.querySelector('title')?.textContent || '' + + // skip if it's a reply (starts with @ mention) + if (description.trim().startsWith('@') || title.trim().startsWith('@')) { + continue + } + + const link = item.querySelector('link')?.textContent.trim() + const cleanTitle = sanitizeHtml(title, { + allowedTags: [], + allowedAttributes: {}, + })?.trim() + + return { text: cleanTitle, url: link } + } + + // fallback to first item if no non-reply found + const firstItem = items[0] + const title = firstItem.querySelector('title').textContent + const link = firstItem.querySelector('link').textContent.trim() const cleanTitle = sanitizeHtml(title, { allowedTags: [], allowedAttributes: {},