Keeping emails sending properly from WordPress can be a little tricky. There are things you can do to improve email deliverability. Routing emails through a transaction email service or a real email account can greatly improve odds that your email will hit your customer’s inbox. However, no matter how good your setup is, all it takes is one unprotected contact form or one misconfigured user registration plugin to be abused by a malicious script and your email reputation will be affected.
Even a “perfect” email solution can unexpectedly be disrupted by abuse
I prefer to configure my customers to send out through Anchor Hosting’s Mailgun via Gravity SMTP. Every time I implement that solution email deliverability is improved with increased visibility for troubleshooting email related issues. I’m reluctant to roll out Mailgun without first doing a detailed review of the website looking for potential holes. Case in point, this past week a customer with the Shared Counts plugin active was hammered with email notifications. Over 186,000 emails were sent within a 2 days timeframe on a website that normally sends 100 emails per year. Yikes! All which could have been prevented by enabling reCaptcha on Shared Counts’ email sharing feature. Luckily Kinsta caught the abuse and halted outgoing emails. We successfully purged the bulk of the bad emails and were able to resume emails.
Keeping everything healthy requires proactive security
The above situation highlights how hard it can be to keep emails sending properly from WordPress. How is the average site owner to know when they installed this plugin that it could have profound email consequences? Any door left open will be found and exploited given enough time. Your email health is tied directly to your ability to identify missing reCaptcha checks or forms without spam prevention. If a bad action is taken against your website, then someone needs to step in and take action.
A simple email health check could uncover a wide range of email delivery issues
While I don’t have a solution to the general management issues around emails and WordPress, I have been thinking about building an email monitor for the last several months. This would work very similar to an uptime site monitor. Instead of checking to make sure the website is online the email health monitor would send out a real test email then confirm it was properly received. This could be a brilliant way to catch and correct the common complaint “Why am I not receiving emails from my website?“.
Now how should I build something like that? Well I already pay for a Mailgun account so my first thought was maybe that could be used to relay emails to a custom PHP script. Up until this point Mailgun has only handled outgoing emails for my customers. Mailgun also supports receiving emails then forwarding via HTTP. Then there is also the question of “how often?” and “what email health checks should I perform?”. These email health checks are going to generate some noise. I don’t want to create too many emails as that can cause issues with email delivery. A safe starting point might be to send out 1 email per site each week.
Checking emails will need to include 2 parts. First is to verify the email was actually received and second to make sure the email looks legitimate based on common email practices. There might even be a paid service I could use to check the likelihood that an email would be delivered. Or maybe come up with my own checklist? Not sure yet. To the code!
No matter how good a plan is, thing tends to change during development.
So after going through many different plans of on how to send and receive health check emails, I ended going a completely different direction when I began developed of a bulk email health monitor. After a few days of development here is what I ended up building:
- A single bash command which talks to each customer website over SSH and sends out an email using WP-CLI with
wp_mail
. - Emails collect to a real email account through Fastmail.
- That email account is connected to Missive with a rule to trigger a webhook.
- The receiving webhook is WordPress Rest API endpoint which reads the email from Missive’s API and collects valid responses into TXT files.
- After the script finishes sending out emails it waits for as many TXT files to collect as possible with a hard cut off after 15 minutes.
- Finally, the script compiles a report showing websites which failed to delivery email responses in that 15 minute window.
I decided to receive emails to a real email provider as it’s a closer to a real world experience. If one of the email health checks land in Fastmail’s spam, then it won’t trigger the web hook and be considered undelivered, which is a good thing. If my customer’s websites are hitting spam then it’s a problem I should be correcting.
Results from the initial email health check monitor
I knew the email health monitor was going to uncover a bunch of preexisting email issues. So let’s dig into the results from my initial email health check.
- There were 92 failed deliveries out of 1737 checked sites, which is a large portion of my production environments. A little over 5% failure rate.
- Out of those 92 failed email deliveries 75 landed into spam
- There were a handful of websites configured with bad/outdated email credentials
- There were a few false positives
Yikes that’s a lot of sites to fix. Too be honest I’m not very surprised. Since recent industry email changes I’ve been seeing an increase of emails from WordPress sites hitting the spam folder. With the email health monitor now complete, I plan to run these scans weekly and correct as needed.