Custom Spam Filtering with Silent Error
Contact Form 7's very limited developer documentation gives this code snippet which is supposed to use your custom PHP logic to identify spam mail and prevent them from being sent.
add_filter( 'wpcf7_spam', function( $spam ) {
if ( $spam ) {
return $spam;
}
if ( false !== stripos( $_POST['your-message'], 'filtered-word' ) ) {
$spam = true;
}
return $spam;
}, 10, 1 );
However, this will result in an error message shown on the form when a message is determined to be spam. This will allow the spammer to adjust their tactics and bypass your filter when they learn how to.
Unfortunately, the documentation does not mention anything about forcing a "Success" message to be shown when a spam mail is sent. However, there is an undocumented filter that we can use to force a "Success" message when a spam mail has been sent. This works as of writing (2025-10-28), and at least for my use case.
add_filter('wpcf7_ajax_json_echo', function ($response, $result) {
if (isset($response['status']) && $response['status'] === 'spam') {
$response['status'] = 'mail_sent';
$response['message'] = 'Email has been sent. Thank you.';
}
return $response;
}, 10, 2);
Here's my own implementation of a custom spam filter that will mark a message as spam if it uses a certain email address or contains words in the forbidden list, which will then show a success message even though the mail wasn't actually sent.
add_filter('wpcf7_spam', function($spam) {
if ($spam) {
return true;
}
$email = isset($_POST['email']) ? trim(strtolower($_POST['email'])) : '';
$message = $_POST['message'] ?? '';
$blocked_emails = [
'[email protected]',
'[email protected]',
];
$banned_words = [
'spam', 'eggs', 'bacon',
];
if (in_array($email, $blocked_emails)) {
return true;
};
foreach ($banned_words as $word) {
if (mb_stripos($message, $word) !== false) {
return true;
}
}
return false;
}, 10, 1 );
add_filter('wpcf7_ajax_json_echo', function ($response, $result) {
if (isset($response['status']) && $response['status'] === 'spam') {
$response['status'] = 'mail_sent';
$response['message'] = 'Your message has been sent.';
}
return $response;
}, 10, 2);