From f571670e13daa179f3644de2e61e907ca7e59230 Mon Sep 17 00:00:00 2001 From: grassblock Date: Wed, 7 May 2025 18:26:08 +0800 Subject: [PATCH] feat: implement Fediverse comments integration --- src/components/Comments.astro | 7 +- .../helper/comments/Fediverse.astro | 249 ++++++++++++++++++ src/config.ts | 22 +- 3 files changed, 268 insertions(+), 10 deletions(-) create mode 100644 src/components/helper/comments/Fediverse.astro diff --git a/src/components/Comments.astro b/src/components/Comments.astro index 8977e72..694dbea 100644 --- a/src/components/Comments.astro +++ b/src/components/Comments.astro @@ -1,5 +1,7 @@ --- import {siteConfig} from "../config"; +import FediverseComments from "./helper/comments/Fediverse.astro"; + const method = siteConfig.comments.type const ArtalkConfig = siteConfig.comments.artalk const giscusConfig = siteConfig.comments.giscus @@ -7,7 +9,7 @@ interface Props { path?: string; } -const { path='/' } = Astro.props; +let { path='/' } = Astro.props; --- {method === 'artalk' &&
@@ -45,4 +47,5 @@ const { path='/' } = Astro.props; crossorigin="anonymous" async > -)} \ No newline at end of file +)} +{method === 'fediverse' && } \ No newline at end of file diff --git a/src/components/helper/comments/Fediverse.astro b/src/components/helper/comments/Fediverse.astro new file mode 100644 index 0000000..9b1017c --- /dev/null +++ b/src/components/helper/comments/Fediverse.astro @@ -0,0 +1,249 @@ +--- + import { siteConfig } from "../../../config"; + + const fediverseConfig = siteConfig.comments.fediverse; + const { + instanceDomain, + useV2api, + token, + useReverseProxy, + reverseProxyUrl, + accountId + } = fediverseConfig; + + interface Props { + path: string; + } + + const { path } = Astro.props; + + // Create the full URL to search for + const fullSiteUrl = Astro.url.host; + const postUrl = `https://${fullSiteUrl}${path.startsWith('/') ? path : '/' + path}`; + + // Define the search API endpoint based on configuration + let searchEndpoint; + if (useReverseProxy && reverseProxyUrl) { + searchEndpoint = reverseProxyUrl; + } else { + const apiVersion = useV2api ? 'v2' : 'v1'; + searchEndpoint = `https://${instanceDomain}/api/${apiVersion}/search`; + } + --- + +
+
+
Loading comments from the Fediverse...
+ + +
+
+
+ + + + \ No newline at end of file diff --git a/src/config.ts b/src/config.ts index a0d1c00..0dbf2b0 100644 --- a/src/config.ts +++ b/src/config.ts @@ -2,7 +2,7 @@ export const siteConfig = { title: '/var/log/mercury', description: 'A blog about software development, technology, and life.', comments: { - type: 'artalk', // 'artalk','giscus','fediverse','hatsu' + type: 'fediverse', // 'artalk','giscus','fediverse','hatsu' artalk: { instanceDomain: '', // the domain of your artalk instance }, @@ -24,14 +24,20 @@ export const siteConfig = { fediverse: { // use Mastodon (compatible) api to search posts and parse replies // it will search for the post's link by default - instanceDomain: '', // the domain of the fediverse instance to search posts from - useV2api: false, // use /api/v2/search instead of /api/v1/search to search on instance using newer version of mastodon - token: process.env.MASTODON_API_TOKEN, // the token to use to authenticate with the fediverse instance, usually a read:search-only token - // or use a reverse proxy api to return posts on instance, useful if you publish the site in SSG mode. - // the instanceDomain and token will be ignored if useReverseProxy is true and reverseProxyUrl is used. - useReverseProxy: false, + // the comments are rendered at the client side (by now) + // a reverse proxy is required in pure client-side rendering mode to get the posts from the fediverse instance + useReverseProxy: true, reverseProxyUrl: '', // the url of the reverse proxy, usually a cloudflare worker proxying the search api - accountId: '' // the account id to search posts from, can be got from api like: https://{instance}/api/v1/accounts/{username without domain part} + // the reverse proxy should be able to handle the following request: + // GET /api/v1/search?q={query}&type=statuses&account_id=12345678 + // GET /api/v1/statuses/12345678/context + // response body should be returned from the origin fediverse instance as-is. + accountId: '', // the account id to search posts from, can be got from api like: https://{instance}/api/v1/accounts/{username without domain part} + // for development purpose only (by now): + // TODO: render the comments on the server-side when in server-side render/hybrid render mode + instanceDomain: '', // the domain of the fediverse instance to search posts from + useV2api: true, // use /api/v2/search instead of /api/v1/search to search on instance using newer version of mastodon/pleroma/akkoma + token: process.env.MASTODON_API_TOKEN, // the token to use to authenticate with the fediverse instance, usually a read:search-only token }, hatsu: { // use hatsu.cli.rs to get replies from the fediverse