From 9dc02102adaa73422f646cd9aca04c6eff1e818e Mon Sep 17 00:00:00 2001 From: Ricardo Date: Tue, 24 Mar 2026 11:47:15 +0100 Subject: [PATCH] fix: deduplicate interactions by author+type+target, not just wm-id Same interaction arriving from webmention.io and conversations API had different wm-id values but same author/type/target. Now normalizes URLs and deduplicates by semantic identity. --- interactions.njk | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/interactions.njk b/interactions.njk index c998a07..f82a9a5 100644 --- a/interactions.njk +++ b/interactions.njk @@ -515,12 +515,23 @@ function interactionsApp() { mergeAndDeduplicate(wmItems, convItems) { const convUrls = new Set(convItems.map(c => c.url).filter(Boolean)); const seen = new Set(); + const seenInteraction = new Set(); const result = []; + const normalizeUrl = (url) => (url || '').replace(/\/$/, ''); + const interactionKey = (item) => { + const author = normalizeUrl(item.author?.url); + const type = item['wm-property'] || ''; + const target = normalizeUrl(item['wm-target']); + return `${author}|${type}|${target}`; + }; + for (const item of convItems) { const key = item['wm-id'] || item.url; - if (key && !seen.has(key)) { + const iKey = interactionKey(item); + if (key && !seen.has(key) && !seenInteraction.has(iKey)) { seen.add(key); + seenInteraction.add(iKey); result.push(item); } } @@ -530,12 +541,16 @@ function interactionsApp() { if (seen.has(wmKey)) continue; if (item.url && convUrls.has(item.url)) continue; + const iKey = interactionKey(item); + if (seenInteraction.has(iKey)) continue; + if (!item.platform) { const detected = this.detectPlatform(item); if (detected) item.platform = detected; } seen.add(wmKey); + seenInteraction.add(iKey); result.push(item); }