First commit

This commit is contained in:
2026-03-25 20:50:17 -03:00
commit c3f3efbf33
6 changed files with 626 additions and 0 deletions

49
README.md Normal file
View File

@@ -0,0 +1,49 @@
# Bluesky Threads — FreshRSS Extension
A FreshRSS extension that enriches Bluesky posts in your RSS feeds by fetching the full reply thread and embedded content via the Bluesky public API, collapsing everything into a single article.
## Features
- Fetches full reply threads when a post is first saved, so API sync clients (Fever, GReader, etc.) receive enriched content immediately
- Automatically refreshes thread content as it ages, with progressively relaxed refresh intervals
- Renders rich text with working links, mentions, and hashtags
- Renders all embed types: images, external link cards, quoted posts, and videos
- No Bluesky account or API credentials required
## Installation
1. Download or clone this repository into FreshRSS's `extensions/` directory. The folder must be named `xExtension-BlueskyThreads`.
2. In FreshRSS, go to **Extensions** and enable **Bluesky Threads**.
## Configuration
In the extension settings, you can set **Thread depth** (default: 10, max: 1000) — how many levels of replies to fetch per post.
## How it works
### Hooks
Two hooks work in tandem so both the web UI and API sync clients receive enriched content:
- **`EntryBeforeInsert`** — fires once when a new entry is first saved. Fetches the thread immediately and stores the rendered HTML.
- **`EntryBeforeDisplay`** — fires on every web render. Checks if the cached thread is stale; if so, re-fetches and writes the updated HTML back to the database.
### Cache & staleness
Thread HTML is cached as JSON files in `DATA_PATH/BlueskyThreads/{md5(url)}.json`. Staleness is determined by the post's age:
| Post age | Cache refresh interval |
|--------------|------------------------|
| < 1 hour | Every 10 minutes |
| < 24 hours | Every 1 hour |
| < 7 days | Every 12 hours |
| 7+ days | Never (frozen) |
On API failure, the stale cache is served as a fallback.
### API endpoints used
All requests go to `public.api.bsky.app` — no authentication required.
- **Handle resolution:** `com.atproto.identity.resolveHandle`
- **Thread fetch:** `app.bsky.feed.getPostThread`