Custom spam filtering

Posts in the developer's cookbook category describe topics that require technical knowledge. Be warned and use the techniques at your own risk. Unless you are an experienced developer, you are strongly advised to ask a professional for support.

Spam protection is mission-critical for web forms. The Contact Form 7 plugin provides several types of spam protection modules to effectively block submission by spammers.

Just like other parts of Contact Form 7, its spam-filtering feature is designed to be highly customizable. In this recipe, I’ll show you how to implement a custom spam filter with simple coding examples.

The wpcf7_spam filter hook

Contact Form 7’s spam filter is implemented as a PHP function that is hooked to the wpcf7_spam filter hook. If a filter function determines that the ongoing submission is spam, the function returns true.

The following PHP code is a simple example of a spam filter. This filter function determines the submission is spam if the user input includes the world-famous spammy word Viagra.

add_filter( 'wpcf7_spam', function( $spam ) {
  if ( $spam ) {
    return $spam;
  }

  if ( false !== stripos( $_POST['your-message'], 'viagra' ) ) {
    $spam = true;
  }

  return $spam;
}, 10, 1 );

Notice that the filter function first checks the $spam variable, and if it is true, it returns the variable without searching “viagra” in the user input.

Why? The initial value set to the $spam variable is false. If you see $spam is true at the beginning of your filter function, it is because there is another filter function hooked to the same wpcf7_spam filter hook (it has higher priority than yours), and it has returned true.

This means that another spam filter has already determined that the submission is spam, and therefore, you don’t need to do additional spam filtering.

Logging spam submission

Since there are several types of spam filters working, it would be helpful if you leave a log that explains which filter marked the submission as spam and why.

To leave a spam log, call the add_spam_log() instance method of the WPCF7_Submission class. add_spam_log() takes an associative array as its only argument, and that array must include the following variables:

  • agent: A unique keyword or name that identifies your custom filter.
  • reason: A short text that describes the reason why the filter has determined the submission is spam.

The following example shows the use of add_spam_log() within the preceding Viagra filter:

add_filter( 'wpcf7_spam', function( $spam ) {
  if ( $spam ) {
    return $spam;
  }

  if ( false !== stripos( $_POST['your-message'], 'viagra' ) ) {
    $spam = true;

    // Leaving a spam log.
    $submission = WPCF7_Submission::get_instance();

    $submission->add_spam_log( array(
      'agent' => 'my_viagra_plugin',
      'reason' => "My plugin detects Viagra.",
    ) );
  }

  return $spam;
}, 10, 1 );

You can view the spam logs with a message storage plugin that supports spam logging. Flamingo is one such plugin, and we recommend it for Contact Form 7 users.