From 4a81b5afab452c3e2332ffaca25a79c3ca66a2fd Mon Sep 17 00:00:00 2001 From: Sven Date: Wed, 18 Mar 2026 08:04:27 +0100 Subject: [PATCH] fix: unfurl corrupted self-filter patch script, drop webmention-sender backend patch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The patch script was corrupted (nested snippets embedded inside template literals). Reconstructed it cleanly with only the two original specs (scheduler + conversations controller). The webmention-sender backend patch is removed — self-Bluesky filtering belongs in the blog sidebar widget, not the backend dashboard. Co-Authored-By: Claude Sonnet 4.6 --- ...atch-conversations-bluesky-self-filter.mjs | 98 +++++++------------ 1 file changed, 33 insertions(+), 65 deletions(-) diff --git a/scripts/patch-conversations-bluesky-self-filter.mjs b/scripts/patch-conversations-bluesky-self-filter.mjs index 9c68ea91..17f85442 100644 --- a/scripts/patch-conversations-bluesky-self-filter.mjs +++ b/scripts/patch-conversations-bluesky-self-filter.mjs @@ -42,56 +42,47 @@ const patchSpecs = [ for (const notification of result.items) { // Skip self-interactions (e.g. own account liking/reposting a syndicated post) if (ownBskyHandle && (notification.author?.handle || "").toLowerCase() === ownBskyHandle) { - const webmentionSenderCandidates = [ - "node_modules/@rmdes/indiekit-endpoint-webmention-sender/lib/controllers/webmention-sender.js", - "node_modules/@indiekit/indiekit/node_modules/@rmdes/indiekit-endpoint-webmention-sender/lib/controllers/webmention-sender.js", - ]; + continue; + } - const patchSpecs = [ - { - name: "conversations-bluesky-scheduler-self-filter", - candidates: schedulerCandidates, - marker: "// Skip self-interactions", - oldSnippet: ` let stored = 0; + let canonicalUrl = null;`, + }, + { + name: "conversations-bluesky-api-self-filter", + candidates: controllerCandidates, + marker: "// Filter out self-interactions from own Bluesky account", + oldSnippet: ` const children = items.map(conversationItemToJf2); - for (const notification of result.items) { - let canonicalUrl = null;`, - newSnippet: ` let stored = 0; + response.set("Cache-Control", "public, max-age=60");`, + newSnippet: ` // Filter out self-interactions from own Bluesky account + const _selfBskyHandle = (process.env.BLUESKY_IDENTIFIER || process.env.BLUESKY_HANDLE || "").replace(/^@+/, "").toLowerCase(); + if (_selfBskyHandle) { + const _selfBskyUrl = "https://bsky.app/profile/" + _selfBskyHandle; + items = items.filter(item => (item.author?.url || "").toLowerCase() !== _selfBskyUrl); + } - // Derive own handle from identifier (strip leading @) - const ownBskyHandle = (credentials.identifier || "").replace(/^@+/, "").toLowerCase(); + const children = items.map(conversationItemToJf2); - for (const notification of result.items) { - // Skip self-interactions (e.g. own account liking/reposting a syndicated post) - if (ownBskyHandle && (notification.author?.handle || "").toLowerCase() === ownBskyHandle) { - continue; - } + response.set("Cache-Control", "public, max-age=60");`, + }, +]; - let canonicalUrl = null;`, - }, - { - name: "conversations-bluesky-api-self-filter", - candidates: controllerCandidates, - marker: "// Filter out self-interactions from own Bluesky account", - oldSnippet: ` const children = items.map(conversationItemToJf2); +async function exists(filePath) { + try { + await access(filePath); + return true; + } catch { + return false; + } +} - response.set("Cache-Control", "public, max-age=60");`, - newSnippet: ` // Filter out self-interactions from own Bluesky account - const _selfBskyHandle = (process.env.BLUESKY_IDENTIFIER || process.env.BLUESKY_HANDLE || "").replace(/^@+/, "").toLowerCase(); - if (_selfBskyHandle) { - const _selfBskyUrl = "https://bsky.app/profile/" + _selfBskyHandle; - items = items.filter(item => (item.author?.url || "").toLowerCase() !== _selfBskyUrl); - } +const checkedFiles = new Set(); +const patchedFiles = new Set(); - const children = items.map(conversationItemToJf2); +for (const spec of patchSpecs) { + let foundAnyTarget = false; - response.set("Cache-Control", "public, max-age=60");`, - }, - { - name: "webmention-sender-bluesky-self-filter", - candidates: webmentionSenderCandidates, - marker: "// Filter out self Bluesky profile from webmention results", - oldSnippet: ` return posts.map((post) => ({ + for (const filePath of spec.candidates) { if (!(await exists(filePath))) { continue; } @@ -99,29 +90,6 @@ const patchSpecs = [ foundAnyTarget = true; checkedFiles.add(filePath); - newSnippet: ` // Filter out self Bluesky profile from webmention results - const _selfBskyHandle = (process.env.BLUESKY_IDENTIFIER || process.env.BLUESKY_HANDLE || "").replace(/^@+/, "").toLowerCase(); - const _selfBskyUrl = _selfBskyHandle ? "https://bsky.app/profile/" + _selfBskyHandle : null; - return posts.map((post) => { - let details = post.properties["webmention-results"]?.details || null; - if (_selfBskyUrl && details && typeof details === "object") { - // Remove any sent/failed/skipped entries where source is own Bluesky profile - for (const key of ["sent", "failed", "skipped"]) { - if (Array.isArray(details[key])) { - details[key] = details[key].filter(entry => (entry.source || entry.author || "").toLowerCase() !== _selfBskyUrl); - } - } - } - return { - url: post.properties.url, - sent: post.properties["webmention-results"]?.sent || 0, - failed: post.properties["webmention-results"]?.failed || 0, - skipped: post.properties["webmention-results"]?.skipped || 0, - details, - timestamp: post.properties["webmention-results"]?.timestamp, - }; - });`, - }, const source = await readFile(filePath, "utf8"); if (spec.marker && source.includes(spec.marker)) {