All checks were successful
Build and Push Docker Image / build (push) Successful in 8m47s
203 lines
6.4 KiB
Markdown
203 lines
6.4 KiB
Markdown
# FFR: Feed to Fediverse Router
|
|
|
|
[](https://forge.lvl0.xyz/lvl0/fedi-feed-router/actions)
|
|
[](https://forge.lvl0.xyz/lvl0/fedi-feed-router/releases)
|
|
[](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
|
|
|
|

|
|
|
|
The dashboard, showing article volume over a selected range, approval and publish
|
|
success rates, and per-feed breakdowns.
|
|
|
|

|
|
|
|
The review queue. Each row is one feed and community pairing, grouped by feed,
|
|
with the routing shown above the headline.
|
|
|
|
## 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.
|
|
|
|
## 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.
|
|
|
|
### docker-compose.yml
|
|
|
|
```yaml
|
|
services:
|
|
app:
|
|
image: forge.lvl0.xyz/lvl0/fedi-feed-router:v1.4.1
|
|
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:
|
|
```
|
|
|
|
### 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`) |
|
|
| `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 fedi-feed-router
|
|
nix-shell
|
|
```
|
|
|
|
The shell prints the available commands and can start the containers for you.
|
|
|
|
| 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 |
|
|
|
|
| Service | URL |
|
|
|---------|-----|
|
|
| App | http://localhost:8000 |
|
|
| Vite | http://localhost:5173 |
|
|
| MariaDB | localhost:3307 |
|
|
| Redis | localhost:6380 |
|
|
|
|
### 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
|
|
|
|
FFR is free software, licensed under the [GNU AGPL-3.0](LICENSE).
|