From 55553ada6a1cb6e499721383e2dcad1d106fbf22 Mon Sep 17 00:00:00 2001 From: Cynthia Foxwell Date: Thu, 17 Apr 2025 21:54:02 -0600 Subject: [PATCH] fedimbed: fedimbed stats --- src/modules/fedimbed.js | 50 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/src/modules/fedimbed.js b/src/modules/fedimbed.js index 814b0b8..98f1379 100644 --- a/src/modules/fedimbed.js +++ b/src/modules/fedimbed.js @@ -942,6 +942,46 @@ async function fetchPost(url, platform, forceMastoAPI = false) { } } +async function getStatsAS(post) { + // agony + let replyCount = 0; + try { + const selfReplies = await signedFetch(post.replies.id + "?page=true", { + headers: { + "User-Agent": FRIENDLY_USERAGENT, + Accept: "application/activity+json", + }, + }).then((res) => res.json()); + replyCount += selfReplies?.items?.length ?? 0; + + const otherReplies = await signedFetch(post.replies.id + "?page=true&only_other_accounts=true", { + headers: { + "User-Agent": FRIENDLY_USERAGENT, + Accept: "application/activity+json", + }, + }).then((res) => res.json()); + replyCount += otherReplies?.items?.length ?? 0; + } catch { + // noop + } + + const stats = []; + if (replyCount > 0) stats.push(`\u21a9 ${statsFormatter.format(replyCount)}`); + if (post.shares?.totalItems ?? 0 > 0) stats.push(`\ud83d\udd01 ${statsFormatter.format(post.shares.totalItems)}`); + if (post.likes?.totalItems ?? 0 > 0) stats.push(`\u2665 ${statsFormatter.format(post.likes.totalItems)}`); + + return stats.join("\u3000"); +} + +function getStatsMasto(post) { + const stats = []; + if (post.replies_count > 0) stats.push(`\u21a9 ${statsFormatter.format(post.replies_count)}`); + if (post.reblogs_count > 0) stats.push(`\ud83d\udd01 ${statsFormatter.format(post.reblogs_count)}`); + if (post.favourites_count > 0) stats.push(`\u2665 ${statsFormatter.format(post.favourites_count)}`); + + return stats.join("\u3000"); +} + async function processUrl(msg, url, spoiler = false, command = false) { let canFedi = await hasFlag(msg.guildID, "fedimbed"); let canBsky = await hasFlag(msg.guildID, "bskyEmbeds"); @@ -993,7 +1033,8 @@ async function processUrl(msg, url, spoiler = false, command = false) { context, contextUrl, emotes = [], - sensitive = false; + sensitive = false, + stats; // Fetch post const postData = await fetchPost(url, platform); @@ -1030,6 +1071,7 @@ async function processUrl(msg, url, spoiler = false, command = false) { .filter((x) => !(x.name ?? x.shortcode)?.endsWith("#.")) .map((x) => ({name: `:${x.name ?? x.shortcode}:`, url: x.url})); sensitive = postData.sensitive; + stats = getStatsMasto(postData); if (postData.in_reply_to_id) { // this url is a dummy and will fail if gone to normally @@ -1139,10 +1181,10 @@ async function processUrl(msg, url, spoiler = false, command = false) { cw = postData.summary; timestamp = postData.published; sensitive = postData.sensitive; + stats = await getStatsAS(postData); if (postData.tag) { let tag = postData.tag; - // gts moment if (!Array.isArray(tag)) tag = [tag]; emotes = tag.filter((x) => !!x.icon).map((x) => ({name: x.name, url: x.icon.url})); } @@ -1191,7 +1233,7 @@ async function processUrl(msg, url, spoiler = false, command = false) { } if (postData.attachment != null) { - // NB: gts doesnt send singular attachments as array + // NB: everyone else except gts doesnt follow the spec (they should be using attachments) const attachments = Array.isArray(postData.attachment) ? postData.attachment : [postData.attachment]; for (const attachment of attachments) { if (attachment.mediaType) { @@ -1409,7 +1451,7 @@ async function processUrl(msg, url, spoiler = false, command = false) { : null, footer: { icon_url: crawled?.icon, - text: platformName, + text: (stats != null && stats != "" ? stats + "\n" : "") + platformName, }, thumbnail: { url: author.avatar,