feat: add fediverse timeline

This commit is contained in:
DIYgod 2024-06-26 22:40:31 +08:00
parent 9efe96bc88
commit 2f8c101bcf
No known key found for this signature in database
2 changed files with 79 additions and 0 deletions

View File

@ -0,0 +1,6 @@
import type { Namespace } from '@/types';
export const namespace: Namespace = {
name: 'Fediverse',
url: 'fediverse.observer',
};

View File

@ -0,0 +1,73 @@
import InvalidParameterError from '@/errors/types/invalid-parameter';
import { Route } from '@/types';
import { parseDate } from '@/utils/parse-date';
import ofetch from '@/utils/ofetch';
export const route: Route = {
path: '/timeline/:account',
categories: ['social-media', 'popular'],
example: '/fediverse/timeline/Mastodon@mastodon.social',
parameters: { account: 'username@domain' },
features: {
requireConfig: false,
requirePuppeteer: false,
antiCrawler: false,
supportBT: false,
supportPodcast: false,
supportScihub: false,
},
name: 'Timeline',
maintainers: ['DIYgod'],
handler,
};
async function handler(ctx) {
const account = ctx.req.param('account');
const domain = account.split('@')[1];
const username = account.split('@')[0];
if (!domain || !username) {
throw new InvalidParameterError('Invalid account');
}
const requestOptions = {
headers: {
Accept: 'application/activity+json',
},
};
const acc = await ofetch(`https://${domain}/.well-known/webfinger?resource=acct:${account}`, requestOptions);
const jsonLink = acc.links.find((link) => link.rel === 'self')?.href;
const link = acc.links.find((link) => link.rel === 'http://webfinger.net/rel/profile-page')?.href;
const self = await ofetch(jsonLink, requestOptions);
const outbox = await ofetch(self.outbox, requestOptions);
const firstOutbox = await ofetch(outbox.first, requestOptions);
const items = firstOutbox.orderedItems;
return {
title: `${self.name || self.preferredUsername} (Fediverse@${account})`,
description: self.summary,
image: self.icon?.url || self.image?.url,
link,
item: items.map((item) => {
const object =
typeof item.object === 'string'
? {
content: item.object,
}
: item.object;
return {
title: object.content,
description: `${object.content}\n${object.attachment?.map((attachment) => `<img src="${attachment.url}" width="${attachment.width}" height="${attachment.height}" />`).join('\n') || ''}`,
link: item.url,
pubDate: parseDate(item.published),
guid: item.id,
};
}),
};
}