rss email digests over ssh because you're a cool kid herald.dunkirk.sh
go rss rss-reader ssh charm
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 157 lines 4.6 kB view raw view rendered
1# Herald 🎏 2 3![herald web interface](https://l4.dunkirk.sh/i/TuJ7meLh1JB9.webp) 4 5This 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 :) 6 7The canonical repo for this is hosted on tangled over at [`dunkirk.sh/herald`](https://tangled.org/@dunkirk.sh/herald) 8 9## Quick Start 10 11```bash 12# Build 13go build -ldflags "-X main.commitHash=$(git log -1 --format=%H)" -o herald . 14 15# Run the server 16./herald serve 17 18# Or with a config file 19./herald serve -c config.yaml 20``` 21 22> **Note:** The commit hash is automatically detected at runtime if not embedded at build time. 23 24## Usage 25 26### Upload a config 27 28Create a `feeds.txt` file: 29 30```text 31=: email you@example.com 32=: cron 0 8 * * * 33=: digest true 34=> https://dunkirk.sh/atom.xml 35=> https://news.ycombinator.com/rss 36=> https://lobste.rs/rss "Lobsters" 37``` 38 39Upload via SCP: 40 41```bash 42scp feeds.txt user@herald.dunkirk.sh: 43``` 44 45### SSH Configuration 46 47Add this to your `~/.ssh/config` for easier access: 48 49```ssh-config 50Host herald 51 HostName herald.dunkirk.sh 52 Port 2223 53 User herald 54``` 55 56Then use: `scp feeds.txt herald:` and `ssh herald ls` 57 58### SSH Commands 59 60```bash 61# Get your fingerprint (for web dashboard) 62ssh herald.dunkirk.sh 63 64# List your configs 65ssh herald.dunkirk.sh ls 66 67# Show config contents 68ssh herald.dunkirk.sh cat feeds.txt 69 70# Delete a config 71ssh herald.dunkirk.sh rm feeds.txt 72 73# Activate/deactivate configs 74ssh herald.dunkirk.sh activate feeds.txt 75ssh herald.dunkirk.sh deactivate feeds.txt 76 77# Run immediately (don't wait for cron) 78ssh herald.dunkirk.sh run feeds.txt 79 80# Show recent activity 81ssh herald.dunkirk.sh logs 82``` 83 84### Web Interface 85 86Visit `http://localhost:8080` for the landing page. 87 88After uploading a config, run `ssh herald.dunkirk.sh` to get your fingerprint, then visit: 89 90- `http://localhost:8080/{fingerprint}` - Your dashboard with config status 91- `http://localhost:8080/{fingerprint}/feeds.xml` - RSS feed for feeds.txt 92- `http://localhost:8080/{fingerprint}/feeds.json` - JSON feed for feeds.txt 93 94## Config Format 95 96### Directives 97 98| Directive | Required | Description | 99| ------------------- | -------- | ------------------------------------------------- | 100| `=: email <addr>` | Yes | Recipient email address | 101| `=: cron <expr>` | Yes | Standard cron expression (5 fields) | 102| `=: digest <bool>` | No | Combine all items into one email (default: true) | 103| `=: inline <bool>` | No | Include article content in email (default: false) | 104| `=> <url> ["name"]` | Yes (1+) | RSS/Atom feed URL, optional display name | 105 106## Configuration 107 108Create a `config.yaml`: 109 110```yaml 111host: 0.0.0.0 112ssh_port: 2222 113http_port: 8080 114 115host_key_path: ./host_key 116db_path: ./herald.db 117 118smtp: 119 host: smtp.example.com 120 port: 587 121 user: sender@example.com 122 pass: ${SMTP_PASS} 123 from: herald@example.com 124 125allow_all_keys: true 126``` 127 128Environment variables can also be used: 129 130- `HERALD_HOST` 131- `HERALD_SSH_PORT` 132- `HERALD_HTTP_PORT` 133- `HERALD_DB_PATH` 134- `HERALD_SMTP_HOST` 135- `HERALD_SMTP_PORT` 136- `HERALD_SMTP_USER` 137- `HERALD_SMTP_PASS` 138- `HERALD_SMTP_FROM` 139 140## Screenshots 141 142here is an example of what an email digest looks like: 143 144![email from harold](https://l4.dunkirk.sh/i/Ck271POS5n0k.webp) 145 146<p align="center"> 147 <img src="https://raw.githubusercontent.com/taciturnaxolotl/carriage/main/.github/images/line-break.svg" /> 148</p> 149 150<p align="center"> 151 <i><code>&copy 2025-present <a href="https://dunkirk.sh">Kieran Klukas</a></code></i> 152</p> 153 154<p align="center"> 155 <a href="https://tangled.org/dunkirk.sh/herald/blob/main/LICENSE.md"><img src="https://img.shields.io/static/v1.svg?style=for-the-badge&label=License&message=O'Saasy&logoColor=d9e0ee&colorA=363a4f&colorB=b7bdf8"/></a> 156 <a href="https://codecov.io/gh/taciturnaxolotl/harold"><img src="https://img.shields.io/codecov/c/github/taciturnaxolotl/harold?style=for-the-badge&logoColor=d9e0ee&colorA=363a4f&colorB=a6da95"/></a> 157</p>