From 1609220a2744c71a648ef0a31205e665214208c7 Mon Sep 17 00:00:00 2001 From: primal Date: Wed, 28 Jan 2026 22:22:59 -0500 Subject: [PATCH] Limit handle subdomain to 18 chars (PDS restriction) The PDS restricts the first segment of local handles to 18 characters, not the AT Protocol spec of 63. Added abbreviation map for long category names: - science-and-environment -> sci-env - entertainment-and-arts -> ent-arts - technology -> tech (when needed) - etc. Fixes "Handle too long" errors for BBC category feeds. Co-Authored-By: Claude Opus 4.5 --- publisher.go | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/publisher.go b/publisher.go index bd4ab73..8442318 100644 --- a/publisher.go +++ b/publisher.go @@ -712,12 +712,13 @@ func stripHTML(s string) string { // DeriveHandleFromFeed generates an AT Protocol handle from a feed URL // Format: {domain}-{category}.1440.news -// AT Protocol allows up to 63 characters per label +// AT Protocol allows up to 63 characters per label, but the PDS +// restricts the first segment to 18 characters for local handles. // Examples: // feeds.bbci.co.uk/news/technology/rss.xml → bbc-technology.1440.news // news.ycombinator.com/rss → ycombinator.1440.news func DeriveHandleFromFeed(feedURL string) string { - const maxSubdomainLen = 63 + const maxSubdomainLen = 18 // PDS limit for first segment // Ensure we have a scheme for parsing if !strings.Contains(feedURL, "://") { @@ -806,6 +807,20 @@ func DeriveHandleFromFeed(feedURL string) string { mainDomain = "bbc" } + // Abbreviations for long category names to fit 18-char limit + categoryAbbrevs := map[string]string{ + "science-and-environment": "sci-env", + "entertainment-and-arts": "ent-arts", + "science-environment": "sci-env", + "entertainment-arts": "ent-arts", + "technology": "tech", + "business": "biz", + "international": "intl", + "environment": "env", + "entertainment": "ent", + "politics": "pol", + } + // Build subdomain: domain + category (from path) var subdomain string if len(pathParts) > 0 { @@ -815,6 +830,13 @@ func DeriveHandleFromFeed(feedURL string) string { if category == "news" && len(pathParts) == 1 { subdomain = mainDomain } else { + // Try to abbreviate if the full subdomain would be too long + fullSubdomain := mainDomain + "-" + category + if len(fullSubdomain) > maxSubdomainLen { + if abbrev, ok := categoryAbbrevs[category]; ok { + category = abbrev + } + } subdomain = mainDomain + "-" + category } } else {