# Herald 🎏 ![herald web interface](https://l4.dunkirk.sh/i/TuJ7meLh1JB9.webp) This was inspired by the sunsetting of [pico.sh/feeds](https://blog.pico.sh/ann-033-moving-rss-to-email-pico-plus) being available outside of `pico+`. It is a totally understandable move from them as their email costs were skyrocketing and they needed to pay for it somehow. This was created to allow me to still get my rss feeds delivered to me each day by email which I have grown quite accustomed to. The config is completely compatible with the `pico.sh` format as of `2026-01-09` and should stay fairly stable. It is also configured over ssh with the slight addition that you can view your feeds on a website as well as I found myself wanting to hot load my feeds into my website :) The canonical repo for this is hosted on tangled over at [`dunkirk.sh/herald`](https://tangled.org/@dunkirk.sh/herald) ## Quick Start ```bash # Build go build -ldflags "-X main.commitHash=$(git log -1 --format=%H)" -o herald . # Run the server ./herald serve # Or with a config file ./herald serve -c config.yaml ``` > **Note:** The commit hash is automatically detected at runtime if not embedded at build time. ## Usage ### Upload a config Create a `feeds.txt` file: ```text =: email you@example.com =: cron 0 8 * * * =: digest true => https://dunkirk.sh/atom.xml => https://news.ycombinator.com/rss => https://lobste.rs/rss "Lobsters" ``` Upload via SCP: ```bash scp feeds.txt user@herald.dunkirk.sh: ``` ### SSH Configuration Add this to your `~/.ssh/config` for easier access: ```ssh-config Host herald HostName herald.dunkirk.sh Port 2223 User herald ``` Then use: `scp feeds.txt herald:` and `ssh herald ls` ### SSH Commands ```bash # Get your fingerprint (for web dashboard) ssh herald.dunkirk.sh # List your configs ssh herald.dunkirk.sh ls # Show config contents ssh herald.dunkirk.sh cat feeds.txt # Delete a config ssh herald.dunkirk.sh rm feeds.txt # Activate/deactivate configs ssh herald.dunkirk.sh activate feeds.txt ssh herald.dunkirk.sh deactivate feeds.txt # Run immediately (don't wait for cron) ssh herald.dunkirk.sh run feeds.txt # Show recent activity ssh herald.dunkirk.sh logs ``` ### Web Interface Visit `http://localhost:8080` for the landing page. After uploading a config, run `ssh herald.dunkirk.sh` to get your fingerprint, then visit: - `http://localhost:8080/{fingerprint}` - Your dashboard with config status - `http://localhost:8080/{fingerprint}/feeds.xml` - RSS feed for feeds.txt - `http://localhost:8080/{fingerprint}/feeds.json` - JSON feed for feeds.txt ## Config Format ### Directives | Directive | Required | Description | | ------------------- | -------- | ------------------------------------------------- | | `=: email ` | Yes | Recipient email address | | `=: cron ` | Yes | Standard cron expression (5 fields) | | `=: digest ` | No | Combine all items into one email (default: true) | | `=: inline ` | No | Include article content in email (default: false) | | `=> ["name"]` | Yes (1+) | RSS/Atom feed URL, optional display name | ## Configuration Create a `config.yaml`: ```yaml host: 0.0.0.0 ssh_port: 2222 http_port: 8080 host_key_path: ./host_key db_path: ./herald.db smtp: host: smtp.example.com port: 587 user: sender@example.com pass: ${SMTP_PASS} from: herald@example.com allow_all_keys: true ``` Environment variables can also be used: - `HERALD_HOST` - `HERALD_SSH_PORT` - `HERALD_HTTP_PORT` - `HERALD_DB_PATH` - `HERALD_SMTP_HOST` - `HERALD_SMTP_PORT` - `HERALD_SMTP_USER` - `HERALD_SMTP_PASS` - `HERALD_SMTP_FROM` ## Screenshots here is an example of what an email digest looks like: ![email from harold](https://l4.dunkirk.sh/i/Ck271POS5n0k.webp)

© 2025-present Kieran Klukas