Handle HTML Forms Through Email With MailyGo
You may have already notice the contact form on this blog. Until recently, it was handled by Netlify and used a serverless function to send an email both to me and the submitter. This worked fine, but was far from ideal because I had to trust the data to a third party (Netlify).
As I was already running a server (with Nextcloud and Mastodon), I looked for a self-hosted solution and found MailyGo from Jan-Lukas Else. A small tool written in Go that allows send HTML forms through email. Exactly what I was looking for!
I just needed to tailor it a little bit to my use case. A good challenge as this was my first time working with Go. Keep that in mind and be kind when you review my code, please!
So, there’s the list of changes I made:
When a form is placed online it’s a matter of time until it get some bots’ attention and being targeted with spam. To fight it, the original version of MailyGo already used an honeypot field, a spamlist and integrated Google Safe Browsing to check URLs. And that seemed enough.
But I didn’t want to use any third party, even less Google! And unfortunately the honeypot field and spamlist alone shown insufficient.
I got some bots sending a particular field (submit) that wasn’t part of the form. And so, I created a denylist, a list of fields names that MailyGo will look for and, if present, mark the submission as spam.
I too got bots that grabbed the URL of MailyGo and posted a submission directly to it, bypassing the form. To prevent this, I created the ability to use a token to assure only the submissions that come from the form are handle by MailyGo. This token can be any combination of letters and numbers. If a
TOKEN is defined on configuration, MailyGo will look for a field named
_token. If this field doesn’t exist or its value doesn’t match the one defined on configuration the submission will be marked as spam.
I’m using this set of solutions for more than a week now with zero spam. Seems enough. At least for now!
An that’s it, my fork of MailyGo!