Recently, we got a lot of spam comments with emails "[email protected]" on the Meta Box website. These comments even pass the check by the plugin "Simple CloudFlare Turnstile", which I'm using to prevent spam. While fighting with that, I thought why don't we block block all comments if the email has a specific domain?
In this article, I'll show you a simple way to block all comments by domain, where you can put it in a functionality plugin for your website and avoid all of this annoying thing.
Blocking comments with default WordPress blacklist
WordPress has a built-in feature to block comments if the comment author's name, email, URL, IP address, or content contains any of the words defined in Settings > Discussion > Disallowed Comment Keys.
When I put "@tempmail.de" in the blacklist, WordPress indeed recognizes these comments and puts them immediately in the Trash. So far so good.
However, the problem with this method is that WordPress still has to process the comments. And the worst thing is that those comments are inserted into the database. Writing to the database is a heavy task. On a high-traffic website, this can cause a performance problem. Especially, when you're the target of a spam attack campaign.
Finally, you have to manually clean up your database by emptying your Trash.
So, I look for a better way to block comments before they're processed or inserted into the database.
Blocking comments before saving into the database
After checking the WordPress source code, I found an interesting filter pre_comment_approved
. This filter allows us to check the comment data and returns an approved status: spam, trash, pending or approved.
And if there are any errors, we can return an instance of WP_Error
class to let WordPress knows. In that case, WordPress won't insert the comment into the database. That's exactly what I want!
So, I made a snippet to check the comment email against a blacklist of domains like this:
add_filter( 'pre_comment_approved', function( $approved, $commentdata ) {
$blacklist = ['tempmail.de'];
foreach ( $blacklist as $domain ) {
if ( str_contains( $commentdata['comment_author_email'], "@$domain" ) ) {
wp_die( 'Please do not spam. Thank you.', 'Your comment is blocked.', 403 );
}
}
return $approved;
}, 10, 2 );
In this snippet, I can return an instance of WP_Error
as WordPress instructs. Unfortunately, WordPress doesn't show or log this error anywhere. Submitting a comment with a blacklisted domain simply returns a white death screen. So it's hard to know if it works.
Instead of that, I use wp_die
to stop the process and display an error message immediately. Because this is a spam comment, doing so is totally fine. I also set the response status to 403 which means "Forbidden" - an appropriate status in this case!
With wp_die
, you can test the snippet easily. Just go to a post and submit a comment with a domain in the blacklist and you'll see the error message!
And if you notice any spam comments from another domain, simply add it to the $blacklist
variable above.
From now, all these comments are stopped and blocked before they're processed or inserted into the database. Your website will be fast, with no database update, and no trash in the database.