summaryrefslogtreecommitdiff
path: root/src/utils/webmentions.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils/webmentions.ts')
-rw-r--r--src/utils/webmentions.ts115
1 files changed, 0 insertions, 115 deletions
diff --git a/src/utils/webmentions.ts b/src/utils/webmentions.ts
deleted file mode 100644
index 8edfd90..0000000
--- a/src/utils/webmentions.ts
+++ /dev/null
@@ -1,115 +0,0 @@
-import { WEBMENTION_API_KEY } from "astro:env/server";
-import * as fs from "node:fs";
-import type { WebmentionsCache, WebmentionsChildren, WebmentionsFeed } from "@/types";
-
-const DOMAIN = import.meta.env.SITE;
-const CACHE_DIR = ".data";
-const filePath = `${CACHE_DIR}/webmentions.json`;
-const validWebmentionTypes = ["like-of", "mention-of", "in-reply-to"];
-
-const hostName = new URL(DOMAIN).hostname;
-
-// Calls webmention.io api.
-async function fetchWebmentions(timeFrom: string | null, perPage = 1000) {
- if (!DOMAIN) {
- console.warn("No domain specified. Please set in astro.config.ts");
- return null;
- }
-
- if (!WEBMENTION_API_KEY) {
- console.warn("No webmention api token specified in .env");
- return null;
- }
-
- let url = `https://webmention.io/api/mentions.jf2?domain=${hostName}&token=${WEBMENTION_API_KEY}&sort-dir=up&per-page=${perPage}`;
-
- if (timeFrom) url += `&since${timeFrom}`;
-
- const res = await fetch(url);
-
- if (res.ok) {
- const data = (await res.json()) as WebmentionsFeed;
- return data;
- }
-
- return null;
-}
-
-// Merge cached entries [a] with fresh webmentions [b], merge by wm-id
-function mergeWebmentions(a: WebmentionsCache, b: WebmentionsFeed): WebmentionsChildren[] {
- return Array.from(
- [...a.children, ...b.children]
- .reduce((map, obj) => map.set(obj["wm-id"], obj), new Map())
- .values(),
- );
-}
-
-// filter out WebmentionChildren
-export function filterWebmentions(webmentions: WebmentionsChildren[]) {
- return webmentions.filter((webmention) => {
- // make sure the mention has a property so we can sort them later
- if (!validWebmentionTypes.includes(webmention["wm-property"])) return false;
-
- // make sure 'mention-of' or 'in-reply-to' has text content.
- if (webmention["wm-property"] === "mention-of" || webmention["wm-property"] === "in-reply-to") {
- return webmention.content && webmention.content.text !== "";
- }
-
- return true;
- });
-}
-
-// save combined webmentions in cache file
-function writeToCache(data: WebmentionsCache) {
- const fileContent = JSON.stringify(data, null, 2);
-
- // create cache folder if it doesn't exist already
- if (!fs.existsSync(CACHE_DIR)) {
- fs.mkdirSync(CACHE_DIR);
- }
-
- // write data to cache json file
- fs.writeFile(filePath, fileContent, (err) => {
- if (err) throw err;
- console.log(`Webmentions saved to ${filePath}`);
- });
-}
-
-function getFromCache(): WebmentionsCache {
- if (fs.existsSync(filePath)) {
- const data = fs.readFileSync(filePath, "utf-8");
- return JSON.parse(data);
- }
- // no cache found
- return {
- lastFetched: null,
- children: [],
- };
-}
-
-async function getAndCacheWebmentions() {
- const cache = getFromCache();
- const mentions = await fetchWebmentions(cache.lastFetched);
-
- if (mentions) {
- mentions.children = filterWebmentions(mentions.children);
- const webmentions: WebmentionsCache = {
- lastFetched: new Date().toISOString(),
- // Make sure the first arg is the cache
- children: mergeWebmentions(cache, mentions),
- };
-
- writeToCache(webmentions);
- return webmentions;
- }
-
- return cache;
-}
-
-let webMentions: WebmentionsCache;
-
-export async function getWebmentionsForUrl(url: string) {
- if (!webMentions) webMentions = await getAndCacheWebmentions();
-
- return webMentions.children.filter((entry) => entry["wm-target"] === url);
-}