50 lines
2.1 KiB
Markdown
50 lines
2.1 KiB
Markdown
# 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`
|