fedi-feed-router/README.md

204 lines
6.4 KiB
Markdown
Raw Permalink Normal View History

# FFR: Feed to Fediverse Router
2026-01-23 00:30:05 +01:00
[![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.
2026-01-23 00:30:05 +01:00
## Features
- **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.
2026-01-23 00:30:05 +01:00
## Self-hosting
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.
2026-01-23 00:30:05 +01:00
### docker-compose.yml
```yaml
services:
app:
image: forge.lvl0.xyz/lvl0/fedi-feed-router:v1.4.0
2026-01-23 00:30:05 +01:00
container_name: ffr_app
restart: always
ports:
- "8000:8000"
environment:
APP_KEY: "${APP_KEY}"
APP_URL: "${APP_URL}"
DB_DATABASE: "${DB_DATABASE}"
DB_USERNAME: "${DB_USERNAME}"
DB_PASSWORD: "${DB_PASSWORD}"
REDIS_HOST: redis
REDIS_PORT: 6379
volumes:
- app_storage:/app/storage
depends_on:
- db
- redis
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/up"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
db:
image: mariadb:11
container_name: ffr_db
restart: always
environment:
MYSQL_DATABASE: "${DB_DATABASE}"
MYSQL_USER: "${DB_USERNAME}"
MYSQL_PASSWORD: "${DB_PASSWORD}"
MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD}"
volumes:
- db_data:/var/lib/mysql
redis:
image: redis:7-alpine
container_name: ffr_redis
restart: always
volumes:
- redis_data:/data
volumes:
db_data:
redis_data:
app_storage:
2025-06-30 20:29:55 +02:00
```
### Environment variables
2025-08-15 10:32:28 +02:00
2026-01-23 00:30:05 +01:00
| 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`) |
2026-01-23 00:30:05 +01:00
| `DB_DATABASE` | Yes | Database name |
| `DB_USERNAME` | Yes | Database user |
| `DB_PASSWORD` | Yes | Database password |
| `DB_ROOT_PASSWORD` | Yes | MariaDB root password |
2025-08-15 10:32:28 +02:00
## 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.
2026-01-23 00:30:05 +01:00
## Development
2025-06-30 20:29:55 +02:00
2026-01-23 00:30:05 +01:00
### NixOS / Nix
2025-06-30 20:29:55 +02:00
2026-01-23 00:30:05 +01:00
```bash
git clone https://forge.lvl0.xyz/lvl0/fedi-feed-router.git
cd fedi-feed-router
2026-01-23 00:30:05 +01:00
nix-shell
2025-06-30 20:29:55 +02:00
```
2025-06-30 21:28:15 +02:00
The shell prints the available commands and can start the containers for you.
2025-08-02 03:07:27 +02:00
2026-01-23 00:30:05 +01:00
| Command | Description |
|---------|-------------|
| `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 |
2025-08-02 03:07:27 +02:00
2026-01-23 00:30:05 +01:00
| Service | URL |
|---------|-----|
| App | http://localhost:8000 |
| Vite | http://localhost:5173 |
| MariaDB | localhost:3307 |
| Redis | localhost:6380 |
2025-08-02 03:07:27 +02:00
### Other platforms
2025-08-02 03:07:27 +02:00
2026-01-23 00:30:05 +01:00
Contributions welcome for development setup instructions on other platforms.
2025-08-02 03:07:27 +02:00
## Contributing
2025-08-02 03:07:27 +02:00
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.
2025-08-02 03:07:27 +02:00
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
2025-08-15 10:32:28 +02:00
FFR is free software, licensed under the [GNU AGPL-3.0](LICENSE).