Totally Not a Workaround

/

I have been using the free tier of a particular service for a while now. The service is very good and does its job well. But it has very ridiculous limitations/restrictions on its free tier. The most annoying of them all is the inability to receive notifications via anything but email unless you upgrade.

I wanted to upgrade to one of the service’s paid tiers, but all the tiers have features that I don’t need and limits that exceed anything that I would ever use in a lifetime.

So, I decided to do something different.

Given that the service allows notifications via email on the free tier, couldn’t I somehow intercept those emails, parse them, extract the information I need, and then send it to the service of my choosing?

I could indeed!

My journey began by using Gmail’s email filters, n8n, and Pushover. When I would receive an email from the service, I would give it a label, mark it as read, and then, in n8n, I used an “On message received” trigger + a “Code in JavaScript” action to extract the information I needed from the email using string manipulation and finally a “Push a message” action to, well, push a notification to my devices.

That worked OK, but there was a problem: the “On message received” trigger uses polling with a 1-minute poll interval. That meant it would take at least 1 minute for the trigger to fire.

I wanted instant notifications.

So, I started looking online for email webhook services. Basically, services that give you a mailbox that, whenever an email is received, a webhook is triggered with the raw/parsed email content.

I found many such services, including:

But they all either:

I don’t want to pay for something I know I won’t be using much, nor do I want to keep working around restrictive free tiers.

So, I decided to create my own!

I won’t go into detail here, but basically, I looked up the relevant SMTP RFCs (which are https://www.rfc-editor.org/rfc/rfc5321 and https://www.rfc-editor.org/rfc/rfc7504 for anybody wondering) and, using Go, I implemented a simple inbound-only email server that would receive emails, parse them, log them in an NDJSON file, and fire webhooks depending on which mailboxes the email was intended for.

It took me a couple of Fridays as I wasn’t in a hurry, but it was a pretty straightforward process.

Oh, and the reasons I chose Go over something like Node.js or Bun are mainly binary size and the standard library’s richness. I had to use exactly zero dependencies, since Go’s stdlib had everything I needed, and the binary size was ~6.5 megabytes.

So, now, for example, I was able to send emails to [email protected] and that would trigger an n8n webhook that would parse the raw email content (using postal-mime) and create a to-do in whatever service I used for that, using whatever the parsed email contained.

And, sticking to the free-everything theme, I hosted the email server on a small, old laptop I had lying around at home.

Back to the OG problem.

I was now able to replace the “On message received” trigger with a webhook trigger in n8n, set up the service I use to send emails to a specific fake mailbox instead of my Gmail, and voila! Whenever the service sent an email, the server would trigger the n8n webhook, parse the email, and send a Pushover notification!

I achieved mostly what I needed: instant (or as instant as email allows) notifications, completely for free.

But the entire thing wasn’t actually 100% free; I was still using Pushover, which offers a 30-day trial and is relatively cheap at USD 5 (one-time) after that.

You might think that I would pay the 5 bucks and get it over with, but you’d be wrong!

Again, using Go, I wrote a web API with two endpoints: one to establish an SSE connection and another to send a notification to one or more connected SSE clients.

And using Jetpack Compose, I quickly wrote an app that connected to the web API and pushed notifications whenever it received a server-sent event.

Surprisingly, of all the things I had done so far, the most difficult and annoying part was dealing with the mind-numbing number of limitations and gotchas around background/foreground services on Android. Still, since this is an app for me only and I control all the devices on which it will be installed, I got it working without issues for the most part.

So the final pipeline became: service email → my self-hosted inbound email server → n8n webhook → my tiny notification API → my Android app via SSE.

n8n workflow with the following nodes: Webhook → Parse Email → Extract Title & URL → HTTP Request (POST to my notification API)

This is a completely reasonable and proportionate solution to the problem of not wanting to pay for a higher-tier plan.

Did I spend far more time building this than the upgrade would have cost me? Almost certainly. But that was never really the point. The point was that I didn’t want features I wouldn’t use, limits I didn’t need, or yet another subscription for something so small. I wanted a solution that fit my use case, and in the process I ended up with a bunch of small, reusable tools: an inbound email server, a lightweight notification system, and a better understanding of SMTP, webhooks, and Android background execution.

So yes, this started as a way to get free instant notifications. But it also became a reminder that sometimes the best side projects come from mild annoyance, stubbornness, and the refusal to accept “just upgrade” as the only answer.


Enjoy this post?

If you found this content helpful, consider sharing it with others, or if you'd like to support my work directly, you can buy me a coffee on Ko-fi.

Your support helps me create more awesome content. Thank you!