A lightweight service meant to run on a Raspberry Pi that monitors an RSS feed for new content and emails subscribers when new posts are published. The service also manages email subscriptions through a simple form that can be embedded on a website, with a Cloudflare Worker acting as a secure proxy for subscription requests.
You're a good candidate for this software if:
- You have a statically-hosted website/blog with an RSS feed
- You want to offer newsletter updates to tens of people
- You use or want to use Cloudflare for DNS
- You have a Raspberry Pi or some other machine in your closet
- You're relatively tech-savvy
- You're
cheaptoo frugal to pay for a newsletter service like MailChimp
I wrote about this project on my website.
- RSS Monitoring: Checks an RSS feed every hour for new posts
- Email Notifications: Sends styled HTML emails to subscribers when new content is published
- Subscription Management: Handles subscriber sign-ups and (in the future) unsubscribes
- Anti-Spam Protection: Simple rate limiting and email validation
- Monitoring: Uses ntfy.sh for functionality, alerts, and health monitoring
- Dashboard: Simple monitoring dashboard to check service status
- Security: Cloudflare Worker proxy for subscription requests
┌─────────────┐ ┌───────────────┐ ┌───────────────┐
│ Website │ │ Cloudflare │ │ ntfy.sh │
│ Form │────▶│ Worker │────▶│ (Subscribe) │
└─────────────┘ └───────────────┘ └───────┬───────┘
│
▼
┌─────────────┐ ┌────────────────┐ ┌───────────────┐
│ Email │ │ rsspberry2email│ │ Subscriber │
│ Inbox │◀────│ Service │◀────│ Management │
└─────────────┘ └───────┬────────┘ └───────────────┘
│
▼
┌───────────────┐
│ RSS Feed │
│ Monitoring │
└───────────────┘
- Node.js v16 or higher
- Raspberry Pi or similar server (always-on)
- Brevo account for email delivery
- Cloudflare account (for the subscription proxy)
- ntfy.sh topics
git clone https://github.com/MattSayar/rsspberry2email.git
cd rsspberry2emailThe setup script will create necessary directories, install dependencies, and set up configuration files:
./scripts/setup.shThis script will:
- Create data and logs directories
- Install npm dependencies
- Create a .env file from the template (edit with your own values!)
- Generate systemd service files
- Set up log rotation
- Create a ntfy.sh account (or not, I'm not your dad)
- Create unique, hard-to-guess topics (ntfy.sh can generate them for you)
- Do that three times for alerts, subscribes, and unsubscribes (coming soon-ish!)
- You can view a topic anytime at https://ntfy.sh/\[whatever\]
Raspberry Pis' architecture (linux arm LE) doesn't support wrangler CLI-based installs. Here is how to configure Cloudflare via the UI.
- Log in to your Cloudflare dashboard at https://dash.cloudflare.com/
- Navigate to "Workers & Pages" from the sidebar
- Click "Create application" and select "Create Worker"
- Give your worker a name (e.g., "subscribe-proxy")
- In the editor, paste the code from
subscribe-proxy/index.js - Click "Save and Deploy"
- In the Cloudflare dashboard, go to "Workers & Pages"
- Click on "Storage and Databases > KV" in the sidebar
- Click "Create namespace"
- Name it
RATE_LIMIT_NAMESPACEand click "Add" - Go back to your Worker
- Click on "Settings" and then "Variables and Secrets"
- Under "Bindings", click the "+ Add" binding
- Set the Variable name to
RATE_LIMIT_NAMESPACEand select your KV namespace - Click "Save"
- Still in your worker's "Variables and Secrets" settings
- Under "Variables and Secrets", click the "+ Add" button
- Add the following variables:
NTFY_SUBSCRIBE_TOPIC: Your ntfy.sh subscription topic (text)
- Click "Save"
- Still in your worker's Settings
- Go to "Triggers" and click the "+ Add" button
- Add a route like
yourdomain.com/api/subscribe* - Click "Save"
Your RSS/Atom feed requires the category send_newsletter with your post in order to send the email, otherwise it will be skipped.
To test email delivery without waiting for a new post:
# Send to all subscribers
npm test
# Send to a specific email
node scripts/test-email.js test@example.comCopy the form in public/subscription-form.html where you'd like on your website and verify the API endpoint URL in the JavaScript fetch call matches your Cloudflare Worker endpoint:
<form id="subscription-form" action="https://yourdomain.com/api/subscribe" method="post">
<!-- Form content -->
</form>- Brevo: 300 emails/day
- ntfy.sh: 250 notifications/day
- Cloudflare: 100,000 Worker requests/day (static assets free)
The service includes a simple monitoring dashboard that shows:
- Service status
- Last successful check
- Subscriber count
- Last post information
Access it at http://your-server-ip:3001/dashboard.html
The service also uses ntfy.sh, a simple pub/sub service, for functionality, monitoring, and alerts. You can go directlyl to those topics in your browser for:
- RSS feed errors
- Email sending failures
- Service health issues
- New subscriptions and unsubscribes
-
Emails not sending
- Check Brevo API key
- Verify sender email is verified in Brevo
- Check logs for specific errors
-
Subscription form not working
- Ensure Cloudflare Worker is deployed correctly
- Check browser console for JavaScript errors
- Verify the API endpoint URL is correct
-
Service not running
- Check systemd service is running correctly
- Verify Node.js is installed and working
- Check logs/ntfy.sh for errors
Logs are stored in the logs directory. Check app.log for the most recent activity.
The subscribers data is stored in data/subscribers.json. Consider making regular backups of this file.
