Flag and Remove WordPress Spam Comments Automatically

James Parsons by James Parsons Updated Jul 1st, 2024 4 Comments

Here's a cool one; I created a little bit of code that nukes almost all WordPress spam comments automatically - even the ones Akismet doesn't catch.

There's one thing WordPress spam comments all have in common:

They almost all have one or more links. In the author URL field, in the comment text itself, or both. Blog comment spam exists almost solely for spam backlink generation, after all. So, we have a pattern that we can work with.

Url In Each

I created this functions.php code that, when added to your WordPress theme's functions.php file, will add a new cron schedule to automatically flags all pending comments that contain a link as "Spam". It checks once per hour, and if it finds a pending comment with a link in the text or in the author website field, it nukes it:

// Flag pending WordPress comments with links as "Spam"

$settings = [
	// Set to true to flag commenters that filled out the website field.
	// This is useful if your comment form does not have this field enabled,
	// as this means all comments with this field filled are bot submissions
	'delete_with_url_field' => true,
	// Set to true to delete comments with one or more links in the content
	'delete_with_link_in_content' => true,
	// Options: 'delete', 'trash', 'spam'.
	// 'delete' permanently removes them. 'trash' or 'spam' moves them
	// to those respective comment folders to be reviewed later.
	'action' => 'spam',
	// (Optional) Add a list of keywords to blacklist. Any comment that
	// contains one of these keywords will be flagged
	'blacklist_keywords' => ['guest post', 'porn', 'free coins', 'skype', 'whatsapp'],
];

// No need to edit below this line
if (!wp_next_scheduled('delete_pending_comments_with_links')) {
	wp_schedule_event(time(), 'hourly', 'delete_pending_comments_with_links');
}
add_action('delete_pending_comments_with_links', 'delete_pending_comments_with_links');
function delete_pending_comments_with_links() {
	global $wpdb, $settings;
	$conditions = [];
	if ($settings['delete_with_url_field']) {
		$conditions[] = "comment_author_url != ''";
	}
	if ($settings['delete_with_link_in_content']) {
		$conditions[] = "comment_content LIKE '%http%'";
	}
	if (!empty($settings['blacklist_keywords'])) {
		foreach ($settings['blacklist_keywords'] as $keyword) {
			$conditions[] = "comment_content LIKE '%$keyword%'";
		}
	}
	$where_clause = implode(' OR ', $conditions);
	$comments = $wpdb->get_results("
		SELECT comment_ID 
		FROM $wpdb->comments 
		WHERE comment_approved = '0' 
		AND ($where_clause)
	");
	foreach ($comments as $comment) {
		switch ($settings['action']) {
			case 'delete':
				wp_delete_comment($comment->comment_ID, true);
				break;
			case 'trash':
				wp_trash_comment($comment->comment_ID);
				break;
			case 'spam':
				wp_spam_comment($comment->comment_ID);
				break;
		}
	}
}
register_deactivation_hook(__FILE__, 'clear_delete_pending_comments_with_links_schedule');
function clear_delete_pending_comments_with_links_schedule() {
	$timestamp = wp_next_scheduled('delete_pending_comments_with_links');
	wp_unschedule_event($timestamp, 'delete_pending_comments_with_links');
}

To add this to your theme's functions.php file, you want to plop it at the bottom of this file:

  • /wp-content/themes/{your-active-theme-name}/functions.php

All done! You now have a little less work to do every week.

Configure Settings

I recently modified this script to have an optional "Settings" section that you can dial in to your liking. Everyone has different preferences with how they want their spam comments handled, so now you can easily change some of these things.

By default, this script is configured to mark any comment with a URL in the author website field OR in the comment text itself as "Spam".

The code comments are pretty self-explanatory, but here's a quick breakdown of each setting:

1. Flag Comments With A Comment Author URL

// Set to true to delete comments with a URL in the Website field.
// Useful if your comment form does not have the website field enabled,
// as that means 100% of comments with a URL filled out are automated spam
'delete_with_url_field' => true,

This bit is for comments that have an author URL filled out. You know on some comment forms how you can enter Name, Email, Website, Comment? Yeah, this is for when that "Website" field is filled out.

Some comment forms (like mine) don't actually have a website field visible at all. So, how exactly are comments still getting through with it filled out? Exactly - it's from bots! Not a single human comment will have this field filled out because it's not visible. Bots are sending automated POST requests, which are a different story.

So, if you don't let authors enter a website field when commenting either, you can keep this as "true". If you do ask for a website on your comment form, I recommend you change this to "false".

2. Flag Comments With A URL in The Comment Text

// Set to true to delete comments with one or more links in the content
'delete_with_link_in_content' => true, 

This will remove comments if they have a link in the comment text itself.

What does this mean? Basically if the comment is something like this:

"Visit us at https://example.com today for something you never cared about…."

That comment text has a URL directly in the body itself. These are overwhelmingly spam comments; over 99% of them. I recommend leaving this to true by default.

3: Choose What to Do With Flagged Comments

// Options: 'delete', 'trash', 'spam'. Delete permanently removes them.
// Trash or Spam will hide them in those respective comment folders
'action' => 'spam', 

This bit lets you decide what to do with the spam comment once it's found.

  • The "spam" setting moves it to the "Spam" folder in comments. WordPress doesn't automatically delete spam comments by deafult, but Akismet automatically deletes spam comments after 15 days (if you have that plugin installed and configured). This setting is my recommended action.
  • The "trash" setting moves it to the "Trash" folder in comments. Comments are "deleted", but they can be seen and recovered in that folder. They are automatically deleted by WordPress after 30 days.
  • The "delete" setting nukes the comment and it's never coming back. There's no way to undo this action. There's really not a good argument for this option unless you are trying to save a few kb in database size. It's good to know which comments are being deleted, and this setting won't do that for you.

4/4: Blacklist by Keyword

// (Optional) Add a list of keywords to blacklist. Any comment that
// contains one of these keywords will be flagged
'blacklist_keywords' => ['guest post', 'porn', 'free coins', 'skype', 'whatsapp'],

This one is also self explanatory; the settings also contains a keyword blacklist. If you spot a pattern in your spam comments and there are no links in them, you can blacklist by keyword.

I get a lot of guest post spam, so I used that keyword as an example. You can add additional keywords in here - as many as you want. Just be careful with the formatting to make sure they are each comma seperated and that each one is wrapped with apostraphes 'like this'. Also, make sure that you aren't blacklisting any common words or you may accidentally some good comments.

What Do You Think?

I personally use the original code and settings at the top of this post.

My site gets thousands of spam comments every month, so I need all the help I can get. I very rarely get legitimate comments with links in them, and when I do find them, it's usually a low-effort comment that were created just so the author could share their website. I admire the hustle, but these aren't the types of comments I want to approve anyway...

Please let me know in the comments if this helped you! Don't add a link in your comment though or it will get nuked by this handy script 😉

Related Code Snippets

Written by James Parsons

James Parsons is the founder and CEO of Content Powered, a premier content marketing agency that leverages nearly two decades of his experience in content marketing to drive business growth. Renowned for founding and scaling multi-million dollar eCommerce businesses through strategic content marketing, James has become a trusted voice in the industry, sharing his insights in Search Engine Watch, Search Engine Journal, Forbes, Entrepreneur, Inc, and other leading publications. His background encompasses key roles across various agencies, contributing to the content strategies of major brands like eBay and Expedia. James's expertise spans SEO, conversion rate optimization, and effective content strategies, making him a pivotal figure in the industry.