A Week with Feed Canary

December 28, 2023 4 min read

Building in public, one week in.

Last week I wrote and shared a little Laravel app for monitoring RSS feeds.

I got it using a queue to regularly check for 200 responses, make sure feed XML is valid, and send email notifications if the status changes. Drew a little bird in Procreate to be the mascot.

Normally I build things like this in private, collect a list of improvements I can never keep up with, and then move on to something else—so this is an experiment to start with something of value, share it, and see where that goes instead.

I mentioned it here and on Mastodon and didn’t expect anyone to notice, so I was pleasantly surprised by all the likes and boosts and a few emails. A modest but not-overwhelming number of people added their feeds to the pile.

Some asked whether I’d open source the project, which seems like a great idea if I can get comfortable sharing my code. I want it to be reasonably resilient, well documented, and intentional, and I’m anxious that I’ve unwittingly made strange organizational/architectural choices but can get over that part and look forward to critique.

To my relief, it’s been working well! The core checks and notifications are working as expected, and in the past week I’ve made some modest improvements:

  • Required both fields for the signup form to avoid a 500 error 😅
  • Simple dark mode support
  • Support for JSON feeds
  • Fallback for checking XML with feedvalidator.org when W3C’s validator is down (which it is as I’m writing)
  • Simple status page that indicates when the last check happened for my own sanity
  • Humane reply-to address for notification emails
  • 404 response for invalid feed URLs
  • robots: noindex for feed management pages
  • Relevant troubleshooting link on the feed management page when the feed is invalid
  • Reject initial signups that don’t seem to supply feed URLs
  • Basic feature tests

I’ve realized that often feeds are readable when they’re not technically valid, and I’ve introduced laminas/laminas-feed as an initial XML sniff test before continuing to validate the feed format. I expect most people want their feed to be not-malformed rather than perfectly valid, but for now I’m holding the latter as the ideal. Seems better to keep the checks simple rather than introduce tiers of “healthiness.”

Sentry has been great for monitoring, though I’m going to have to scale back performance traces I don’t want to pay more for. (They’re lovely and useful though!)

I still have a whole mess of ideas I’ll probably chip away at. Highlights:

  • Email notifications that are more detailed and possibly more fun
  • Measuring check timing as a useful trend
  • Making sure the queue can’t get backed up with duplicate checks and that everything would work just as well with ten times the number of feeds
  • Option to re-send confirmation email
  • Adorable check status badges
  • Public changelog page
  • Fully local validation for RSS and Atom
  • Some thoughtful way of handling duplicate submissions
  • Optionally checking URLs within feeds
  • Being smart with response headers to avoid fetching and re-checking a feed that hasn’t changed

Where’s the line between useful and overthinking it? No idea!

I’m never sure when a given project is done, and this one doesn’t have a path to sustaining itself but so far it’s been inexpensive and fun to work on. More importantly, I think it’s managed to be useful for more than just me!

If you have any ideas, or you’re great with Laravel and want to pick apart my design decisions, I’d love to hear from you!