Avoid Wpforms Spam By Implementing A Custom Honeypot

WPForms is a great form plugin for WordPress. It has an implemented honeypot functionality, but because the plugin is so popular, many spammers know about this honeypot and know, how to not trigger the honeypot. I receive a lot of spam from WPForms forms, that’s why I was looking for a solution to implement a custom honeypot. The following tutorial describes, how to implement a custom honeypot to your forms, to avoid spam messages.

What is a honeypot

A honeypot field is a hidden field, that “normal visitors” cannot see. A bot will trap into this honeypot by entering some data. The forms code checks, if the honeypot field is empty. If it is – everything is fine and the form data will be processed. If the field has some content, a bot / script has entered the data. In that case, the form data will not be processed and the spam will be filtered.

Add a custom honeypot field

The custom honeypot is based on a custom CSS class. So you have to define a CSS class name for your honeypot, in this example it will be my-custom-honeypot. The next step is to add an additional field to your desired form, that will be used as honeypot. Add your selected CSS class (my-custom-honeypot) to the honeypot field. You can apply custom CSS classes in the WPForms form editor by selecting the field – Advanced Options – CSS Classes.

The next step is to hide the honeypot field by adding this CSS to your theme:

.my-custom-honeypot {
    display: none;
}

Add the required PHP code

After adding the required CSS code, add this code to your function.php or a custom plugin:

/**
 * Custom Honeypot Handling
 *
 * @param $honeypot
 * @param $fields
 * @param $entry
 * @param $form_data
 *
 * @return string
 */
function cdy_custom_honeypot( $honeypot, $fields, $entry, $form_data ) {
	// set the desired CSS class
	$name_of_honeypot_css_class = 'my-custom-honeypot';

	$honeypot_field_id = false;
	foreach ( $form_data['fields'] as $form_field ) {
		if ( false !== strpos( $form_field['css'], $name_of_honeypot_css_class ) ) {
			$honeypot_field_id = absint( $form_field['id'] );
		}
	}

	if ( empty( $honeypot_field_id ) ) {
		return $honeypot;
	}

	if ( isset( $entry['fields'][ $honeypot_field_id ] ) && ! empty( $entry['fields'][ $honeypot_field_id ] ) ) {
		$honeypot = 'Custom Honeypot triggered';
	}

	return $honeypot;
}

add_filter( 'wpforms_process_honeypot', 'cdy_custom_honeypot', 10, 4 );

Enable logging

You can debug your honeypot by enabling the WPForms log. This can be done by using this code:

/**
 * Enable WPForms Log
 */
add_action( 'init',
	function () {
		$debug = get_option( 'wpforms_logging' );
		if ( empty( $debug ) || ! in_array( 'spam', $debug ) ) {
			update_option( 'wpforms_logging', [ 'spam' ] );
		}
	} );

/**
 * Make WPForms Log visible
 */
add_filter( 'wpforms_log_cpt',
	function ( $args ) {
		$args['show_ui'] = true;
		unset( $args['capability_type'] );

		return $args;
	}
);

Now you should see a new menu entry “Logs” below the WPForms section of the WordPress backend.

Check everything

Give it a try. Fill out your form and check, if the form is processed normally. If everything works, set a default value for your honeypot field (no placeholder value), reload your form and re-submit the form. The form should not get processed and a new spam log entry should appear. Another option to check the honeypot is to remove the CSS code to show up the honeypot field. Enter any value and submit the form to check, if the honeypot is working.

If everything works fine, you can remove the code that enables the logging (or leave the code where it is for future debugging). Now your custom honeypot should be up and running.