140 - Rewrite the README as a project page
All checks were successful
CI / ci (push) Successful in 15m47s

This commit is contained in:
myrmidex 2026-08-14 21:54:03 +02:00
parent 1b95e9f8aa
commit ced6cfcaac
7 changed files with 108 additions and 32 deletions

138
README.md
View file

@ -1,26 +1,77 @@
# FFR (Feed to Fediverse Router)
# FFR: Feed to Fediverse Router
A Laravel-based application for routing RSS/Atom feeds to Fediverse platforms like Lemmy. Built with Laravel, Livewire, and FrankenPHP for a modern, single-container deployment.
[![CI](https://forge.lvl0.xyz/lvl0/fedi-feed-router/badges/workflows/ci.yml/badge.svg)](https://forge.lvl0.xyz/lvl0/fedi-feed-router/actions)
[![Release](https://img.shields.io/gitea/v/release/lvl0/fedi-feed-router?gitea_url=https%3A%2F%2Fforge.lvl0.xyz)](https://forge.lvl0.xyz/lvl0/fedi-feed-router/releases)
[![License](https://img.shields.io/badge/license-AGPL--3.0-blue)](LICENSE)
Routes news articles to Fediverse communities. FFR polls a set of sources,
extracts each article, and posts it to the Lemmy communities you map it to,
either automatically or after you approve it.
It is meant to run unattended on your own server: point it at a source, map that
source to a community, and let it publish on a schedule you control.
## Screenshots
![Dashboard](docs/screenshots/dashboard-dark.png)
The dashboard, showing article volume over a selected range, approval and publish
success rates, and per-feed breakdowns.
![Articles](docs/screenshots/articles-light.png)
The review queue. Each row is one feed and community pairing, grouped by feed,
with the routing shown above the headline.
## Features
- **Feed aggregation** - Fetch articles from multiple RSS/Atom feeds
- **Fediverse publishing** - Automatically post to Lemmy communities
- **Route configuration** - Map feeds to specific channels with keywords
- **Approval workflow** - Optional manual approval before publishing
- **Queue processing** - Background job handling with Laravel Horizon
- **Single container deployment** - Simplified hosting with FrankenPHP
- **Article routing**: map each source to one or more Lemmy communities, with
optional keyword filtering
- **Approval workflow**: review articles before they publish, or let them go out
automatically
- **Publishing controls**: a global interval and an optional daily cap, so a
source returning a large batch cannot flood a community
- **Dashboard**: articles fetched and published over time, approval and publish
success rates, and per-source and per-community breakdowns
- **Activity log**: a chronological record of what the automation has done
- **Health checks**: warnings for sources that stop producing articles and for
platform credentials that stop working
- **Dark theme**
- **Single container**: FrankenPHP serves the app, with MariaDB and Redis
alongside
## Sources and platforms
FFR ships with parsers for three sources:
| Source | Type |
|--------|------|
| VRT News | Website |
| Belga | Website |
| The Guardian | RSS |
Some sources publish a usable feed and some do not, so a source is either read
from RSS or scraped from its pages. Either way a parser handles it, registered
in `config/feed.php`.
Adding a source means implementing `ArticleParserInterface` (three methods:
`canParse`, `extractData`, `getSourceName`) and registering it. See
[CONTRIBUTING.md](CONTRIBUTING.md).
Lemmy is currently the only supported platform.
## Self-hosting
The production image is available at `forge.lvl0.xyz/lvl0/fedi-feed-router:latest`.
Images are published to `forge.lvl0.xyz/lvl0/fedi-feed-router`. The example below
pins a release tag; check [Releases](https://forge.lvl0.xyz/lvl0/fedi-feed-router/releases)
for the current one, and the [CHANGELOG](CHANGELOG.md) before upgrading.
### docker-compose.yml
```yaml
services:
app:
image: forge.lvl0.xyz/lvl0/fedi-feed-router:latest
image: forge.lvl0.xyz/lvl0/fedi-feed-router:v1.4.0
container_name: ffr_app
restart: always
ports:
@ -70,42 +121,59 @@ ### docker-compose.yml
app_storage:
```
### Environment Variables
### Environment variables
| Variable | Required | Description |
|----------|----------|-------------|
| `APP_KEY` | Yes | Encryption key. Generate with: `echo "base64:$(openssl rand -base64 32)"` |
| `APP_URL` | Yes | Your domain (e.g., `https://ffr.example.com`) |
| `APP_URL` | Yes | Your domain (e.g. `https://ffr.example.com`) |
| `DB_DATABASE` | Yes | Database name |
| `DB_USERNAME` | Yes | Database user |
| `DB_PASSWORD` | Yes | Database password |
| `DB_ROOT_PASSWORD` | Yes | MariaDB root password |
## Usage
On first run FFR walks you through onboarding. After that:
1. **Add a channel** on the Channels page. A channel is a Lemmy community on a
given instance, together with the account that posts to it. The community is
picked from the instance, so a typo cannot create a channel that fails later.
2. **Add a feed** on the Feeds page, choosing one of the supported sources.
3. **Add a route** on the Routes page, mapping a feed to a channel. Keywords on a
route restrict it to articles that match.
Articles are then discovered on a schedule. Each one becomes a row per matching
route, so an article routed to three communities is three separate decisions.
Approve one on the Articles page and it publishes to that route's community;
publishing failures come back to you on the Failed tab rather than retrying
silently.
Publishing runs every five minutes, one article per run, bounded by the daily cap
if you set one.
## Development
### NixOS / Nix
```bash
git clone https://forge.lvl0.xyz/lvl0/fedi-feed-router.git
cd ffr
cd fedi-feed-router
nix-shell
```
The shell will display available commands and optionally start the containers for you.
#### Available Commands
The shell prints the available commands and can start the containers for you.
| Command | Description |
|---------|-------------|
| `dev-up` | Start development environment |
| `dev-down` | Stop development environment |
| `dev-restart` | Restart containers |
| `dev-logs` | Follow app logs |
| `dev-logs-db` | Follow database logs |
| `dev-shell` | Enter app container |
| `dev-artisan <cmd>` | Run artisan commands |
#### Services
| `dev-up` | Start the development environment |
| `dev-down` | Stop the development environment |
| `dev-restart` | Restart the containers |
| `dev-rebuild` | Rebuild the images |
| `dev-shell` | Enter the app container |
| `dev-artisan <cmd>` | Run an artisan command |
| `dev-logs` | Follow the application log |
| `dev-logs-db` | Follow the database log |
| Service | URL |
|---------|-----|
@ -114,14 +182,22 @@ #### Services
| MariaDB | localhost:3307 |
| Redis | localhost:6380 |
### Other Platforms
### Other platforms
Contributions welcome for development setup instructions on other platforms.
## Contributing
Issues and pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for
the development setup, the checks that run in CI, and the commit conventions.
For bugs and questions, use
[Issues](https://forge.lvl0.xyz/lvl0/fedi-feed-router/issues).
## Note on AI assistance
This project was developed with AI assistance.
## License
This project is open-source software licensed under the [AGPL-3.0 license](LICENSE).
## Support
For issues and questions, please use [Issues](https://forge.lvl0.xyz/lvl0/fedi-feed-router/issues).
FFR is free software, licensed under the [GNU AGPL-3.0](LICENSE).

View file

@ -2,7 +2,7 @@
"$schema": "https://getcomposer.org/schema.json",
"name": "lvl0/fedi-feed-router",
"type": "project",
"description": "Routes RSS and Atom feeds to Fediverse platforms such as Lemmy.",
"description": "Routes news articles from RSS and scraped sources to Fediverse communities.",
"keywords": [
"fediverse",
"lemmy",

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 663 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB