gform_entry_is_spam

Description

The gform_entry_is_spam filter is used to mark entries as spam during form submission.

Notifications and add-on feeds will NOT be processed for submissions which are marked as spam.

As the submission completes the default “Thanks for contacting us! We will get in touch with you shortly.” message will be displayed instead of the forms configured confirmation. The gform_confirmation filter can be used to change the message.

Usage

The following would apply to all forms.

add_filter( 'gform_entry_is_spam', 'your_function_name', 10, 3 );

To limit the scope of your function to a specific form, append the form id to the end of the hook name. (format: gform_entry_is_spam_FORMID)

add_filter( 'gform_entry_is_spam_6', 'your_function_name' );

Parameters

  • $is_spam bool

    Indicates if the entry is to be marked as spam.

  • $form Form Object

    The form currently being processed.

  • $entry Entry Object

    The entry being evaluated.

Examples

Basic Usage

This is a basic usage example showing how to use the filter. This example also shows how to add a note to the entry with Gravity Forms 2.7+ to indicate which integration marked it as spam.

add_filter( 'gform_entry_is_spam', 'it_is_all_spam', 10, 3 );
function it_is_all_spam( $is_spam, $form, $entry ) {
	if ( $is_spam ) {
		return $is_spam;
	}

	// Update this with the result of your custom spam check.
	$is_spam = true;

	if ( $is_spam && method_exists( 'GFCommon', 'set_spam_filter' ) ) {
		GFCommon::set_spam_filter( rgar( $form, 'id' ), 'The name of your spam check', 'the reason this entry is being marked as spam' );
	}

	return $is_spam;
}

Integrate with ZeroBounce

This example shows how a field value can be checked by the ZeroBounce Email Validation API.

add_filter( 'gform_entry_is_spam', 'filter_gform_entry_is_spam_zerobounce', 11, 3 );
function filter_gform_entry_is_spam_zerobounce( $is_spam, $form, $entry ) {
	if ( $is_spam ) {
		return $is_spam;
	}

	$field_id = '1'; // The ID of the field containing the email address to be checked.
	$email    = rgar( $entry, $field_id );

	if ( GFCommon::is_invalid_or_empty_email( $email ) ) {
		if ( method_exists( 'GFCommon', 'set_spam_filter' ) ) {
			GFCommon::set_spam_filter( rgar( $form, 'id' ), 'ZeroBounce', 'The email was empty or invalid.' );
		}

		return true;
	}

	$ip = rgars( $form, 'personalData/preventIP' ) ? GFFormsModel::get_ip() : rgar( $entry, 'ip' );

	$request_url = add_query_arg(
		array(
			'email'      => $email,
			'ip_address' => $ip,
			'api_key'    => 'your_api_key_here',
		),
		'https://api.zerobounce.net/v2/validate'
	);

	$response = wp_remote_get( $request_url );

	if ( ! is_wp_error( $response ) && wp_remote_retrieve_response_code( $response ) === 200 ) {
		$response_body = wp_remote_retrieve_body( $response );
		GFCommon::log_debug( __METHOD__ . '(): ' . print_r( $response_body, true ) );

		$is_spam = rgar( json_decode( $response_body, true ), 'status' ) !== 'valid';

		if ( $is_spam && method_exists( 'GFCommon', 'set_spam_filter' ) ) {
			GFCommon::set_spam_filter( rgar( $form, 'id' ), 'ZeroBounce', 'The email was invalid.' );
		}
	}

	return $is_spam;
}

Check field values for URLs

This example shows how you can mark a submission as spam if a field value contains a URL. It checks only fields of the following types: Hidden, Single Line Text, Paragraph.

add_filter( 'gform_entry_is_spam', 'filter_gform_entry_is_spam_urls', 11, 3 );
function filter_gform_entry_is_spam_urls( $is_spam, $form, $entry ) {
	if ( $is_spam ) {
		return $is_spam;
	}

	$field_types_to_check = array(
		'hidden',
		'text',
		'textarea',
	);

	foreach ( $form['fields'] as $field ) {
		// Skipping fields which are administrative or the wrong type.
		if ( $field->is_administrative() || ! in_array( $field->get_input_type(), $field_types_to_check ) ) {
			continue;
		}

		// Skipping fields which don't have a value.
		$value = $field->get_value_export( $entry );
		if ( empty( $value ) ) {
			continue;
		}

		// If value contains a URL mark submission as spam.
		if ( preg_match( '~(https?|ftp):\/\/\S+~', $value ) ) {
			return true;
		}
	}

	return false;
}

IP Rate Limit

This example shows how you can mark a submission as spam if the IP address is the source of multiple submissions.

add_filter( 'gform_entry_is_spam', 'filter_gform_entry_is_spam_ip_rate_limit', 11, 3 );
function filter_gform_entry_is_spam_ip_rate_limit( $is_spam, $form, $entry ) {
	if ( $is_spam ) {
		return $is_spam;
	}

	$ip_address = empty( $entry['ip'] ) ? GFFormsModel::get_ip() : $entry['ip'];

	if ( ! filter_var( $ip_address, FILTER_VALIDATE_IP ) ) {
		return true;
	}

	$key   = wp_hash( __FUNCTION__ . $ip_address );
	$count = (int) get_transient( $key );

	if ( $count >= 2 ) {
		return true;
	}

	$count ++;
	set_transient( $key, $count, HOUR_IN_SECONDS );

	return false;
}

Check Name Field Values

This example shows how you can mark a submission as spam if the first and last name inputs contain the same value.

add_filter( 'gform_entry_is_spam', 'filter_gform_entry_is_spam_name_values', 11, 3 );
function filter_gform_entry_is_spam_name_values( $is_spam, $form, $entry ) {
	if ( $is_spam ) {
		return $is_spam;
	}

	foreach ( $form['fields'] as $field ) {
		// Skipping fields which are administrative or the wrong type.
		if ( $field->is_administrative() || $field->get_input_type() !== 'name' || $field->nameFormat === 'simple' ) {
			continue;
		}

		$first_name = rgar( $entry, $field->id . '.3' );
		$last_name  = rgar( $entry, $field->id . '.6' );

		if ( ! empty( $first_name ) && ! empty( $last_name ) && $first_name === $last_name ) {
			return true;
		}
	}

	return false;
}

Integrate with ipapi.co

This example shows how the ipapi.co service can be used to get the country code for the IP address of the form submitter enabling you to mark submissions as spam if they originate from specified countries.

add_filter( 'gform_entry_is_spam', 'filter_gform_entry_is_spam_ipapi_country', 11, 3 );
function filter_gform_entry_is_spam_ipapi_country( $is_spam, $form, $entry ) {
	if ( $is_spam ) {
		return $is_spam;
	}

	$ip_address = empty( $entry['ip'] ) ? GFFormsModel::get_ip() : $entry['ip'];
	if ( ! filter_var( $ip_address, FILTER_VALIDATE_IP ) ) {
		return true;
	}

	$response = wp_remote_get( sprintf( 'https://ipapi.co/%s/country/', $ip_address ) );
	if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
		return false;
	}

	$response_country_code = trim( wp_remote_retrieve_body( $response ) );
	if ( empty( $response_country_code ) ) {
		return false;
	}

	// The two letter ISO 3166-1 alpha-2 country codes.
	$country_codes = array( 'CN', 'RU' );

	return in_array( $response_country_code, $country_codes );
}

Integrate with iplocate.io

This example shows how the iplocate.io service can be used to get the country code for the IP address of the form submitter enabling you to mark submissions as spam if they originate from specified countries.

add_filter( 'gform_entry_is_spam', 'filter_gform_entry_is_spam_iplocate_country', 11, 3 );
function filter_gform_entry_is_spam_iplocate_country( $is_spam, $form, $entry ) {
	if ( $is_spam ) {
		return $is_spam;
	}

	$ip_address = empty( $entry['ip'] ) ? GFFormsModel::get_ip() : $entry['ip'];
	if ( ! filter_var( $ip_address, FILTER_VALIDATE_IP ) ) {
		return true;
	}

	$response = wp_remote_get( 'https://www.iplocate.io/api/lookup/' . $ip_address );
	if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
		return false;
	}

	$response_body = json_decode( wp_remote_retrieve_body( $response ), true );
	if ( empty( $response_body['country_code'] ) ) {
		return false;
	}

	// The two letter ISO 3166-1 alpha-2 country codes.
	$country_codes = array( 'CN', 'RU' );

	return in_array( $response_body['country_code'], $country_codes );
}

Mark as Not Spam for administrators

This example shows how prevent entries being marked as spam for logged in users with the ‘administrator’ role.

add_filter( 'gform_entry_is_spam', 'gf_admin_is_not_spam', 10, 3 );
function gf_admin_is_not_spam( $is_spam, $form, $entry ) {
	if ( $is_spam && current_user_can( 'administrator' ) ) {
		// Always not spam for users with administrator role.
		$is_spam = false;
		GFCommon::log_debug( __METHOD__ . '(): Entry marked as not spam for administrator role.' );
	}

	return $is_spam;
}

Integrate with Komprehend Abusive Content Classifier

This example shows how you can use the Komprehend Abusive Content Classifier (ParallelDots Abuse API) to mark submissions as spam if Text or Paragraph field values are abusive or offensive.

add_filter( 'gform_entry_is_spam', 'filter_gform_entry_is_spam_komprehend', 11, 3 );
function filter_gform_entry_is_spam_komprehend( $is_spam, $form, $entry ) {
	if ( $is_spam ) {
		return $is_spam;
	}

	$field_types_to_check = array(
		'text',
		'textarea',
	);

	$text_to_check = array();

	foreach ( $form['fields'] as $field ) {
		// Skipping fields which are administrative or the wrong type.
		if ( $field->is_administrative() || ! in_array( $field->get_input_type(), $field_types_to_check ) ) {
			continue;
		}

		// Skipping fields which don't have a value.
		$value = $field->get_value_export( $entry );
		if ( empty( $value ) ) {
			continue;
		}

		$text_to_check[] = $value;
	}

	if ( empty( $text_to_check ) ) {
		return false;
	}

	$response = wp_remote_post( 'https://apis.paralleldots.com/v4/abuse_batch', array(
		'body' => array(
			'text'    => json_encode( $text_to_check ),
			'api_key' => 'your_api_key_here',
		),
	) );

	if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
		GFCommon::log_debug( __METHOD__ . '(): $response => ' . print_r( $response, true ) );

		return false;
	}

	$results = rgar( json_decode( wp_remote_retrieve_body( $response ), true ), 'abuse' );

	if ( empty( $results ) || ! is_array( $results ) ) {
		GFCommon::log_debug( __METHOD__ . '(): $response => ' . print_r( $response, true ) );

		return false;
	}

	// Add the checked text to the results.
	foreach ( $text_to_check as $key => $text ) {
		if ( ! isset( $results[ $key ] ) ) {
			continue;
		}
		$results[ $key ]['text'] = $text;
	}

	// Define the thresholds the scores will be compared with.
	$abuse_threshold = 0.75;
	$hate_threshold  = 0.75;

	foreach ( $results as $result ) {
		// Mark entry as spam if scores are equal to or greater than the thresholds.
		if ( rgar( $result, 'abusive', 0 ) >= $abuse_threshold || rgar( $result, 'hate_speech', 0 ) >= $hate_threshold ) {
			GFCommon::log_debug( __METHOD__ . '(): $results => ' . print_r( $results, true ) );

			return true;
		}
	}

	return false;
}

Integrate with PurgoMalum profanity filter

This example shows how you can use the PurgoMalum profanity filter to mark submissions as spam if Text or Paragraph field values contain words found on the PurgoMalum profanity list.

add_filter( 'gform_entry_is_spam', 'filter_gform_entry_is_spam_purgomalum', 11, 3 );
function filter_gform_entry_is_spam_purgomalum( $is_spam, $form, $entry ) {
	if ( $is_spam ) {
		return $is_spam;
	}

	$field_types_to_check = array(
		'text',
		'textarea',
	);

	$text_to_check = array();

	foreach ( $form['fields'] as $field ) {
		// Skipping fields which are administrative or the wrong type.
		if ( $field->is_administrative() || ! in_array( $field->get_input_type(), $field_types_to_check ) ) {
			continue;
		}

		// Skipping fields which don't have a value.
		$value = $field->get_value_export( $entry );
		if ( empty( $value ) ) {
			continue;
		}

		$text_to_check[] = $value;
	}

	if ( empty( $text_to_check ) ) {
		return false;
	}

	$args = array(
		'text' => urlencode( implode( "\r\n", $text_to_check ) ),
	);

	$response = wp_remote_get( add_query_arg( $args, 'https://www.purgomalum.com/service/containsprofanity' ) );

	if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
		GFCommon::log_debug( __METHOD__ . '(): $response => ' . print_r( $response, true ) );

		return false;
	}

	return wp_remote_retrieve_body( $response ) === 'true';
}

Integrate with Moderation API

This example shows how you can use the Moderation API Toxicity Analyzer to mark submissions as spam if Text or Paragraph field values contain profanity, swearing, racism, threats etc.

add_filter( 'gform_entry_is_spam', 'filter_gform_entry_is_spam_moderationapi', 11, 3 );
function filter_gform_entry_is_spam_moderationapi( $is_spam, $form, $entry ) {
	if ( $is_spam ) {
		return $is_spam;
	}

	$field_types_to_check = array(
		'text',
		'textarea',
	);

	$text_to_check = array();

	foreach ( $form['fields'] as $field ) {
		// Skipping fields which are administrative or the wrong type.
		if ( $field->is_administrative() || ! in_array( $field->get_input_type(), $field_types_to_check ) ) {
			continue;
		}

		// Skipping fields which don't have a value.
		$value = $field->get_value_export( $entry );
		if ( empty( $value ) ) {
			continue;
		}

		$text_to_check[] = $value;
	}

	if ( empty( $text_to_check ) ) {
		return false;
	}

	$response = wp_remote_post( 'https://moderationapi.com/api/v1/moderation/text', array(
		'headers' => array(
			'Authorization' => 'Bearer your_api_key_here',
			'Content-Type'  => 'application/json',
		),
		'body'    => json_encode( array( 'value' => implode( "\r\n", $text_to_check ) ) ),
	) );

	if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
		GFCommon::log_debug( __METHOD__ . '(): $response => ' . print_r( $response, true ) );

		return false;
	}

	$body = json_decode( wp_remote_retrieve_body( $response ), true );
	GFCommon::log_debug( __METHOD__ . '(): $body => ' . print_r( $body, true ) );

	if ( empty( $body['toxicity'] ) || rgar( $body['toxicity'], 'label' ) === 'NEUTRAL' || empty( $body['toxicity']['label_scores'] ) ) {
		return false;
	}

	// Define the thresholds the scores will be compared with; range from 0 (not spam) to 1 (definitely spam).
	$thresholds = array(
		'TOXICITY'       => 0.75,
		'PROFANITY'      => 0.75,
		'DISCRIMINATION' => 0.75,
	);

	foreach ( $thresholds as $key => $threshold ) {
		// Mark entry as spam if score is equal to or greater than the threshold.
		if ( rgar( $body['toxicity']['label_scores'], $key ) >= $threshold ) {
			return true;
		}
	}

	return false;
}

Integrate with Detect Language API

This example shows how you can use the Detect Language API to mark submissions as spam if Text or Paragraph field values aren’t the specified language, in this case English.

add_filter( 'gform_entry_is_spam', 'filter_gform_entry_is_spam_detectlanguage', 11, 3 );
function filter_gform_entry_is_spam_detectlanguage( $is_spam, $form, $entry ) {
	if ( $is_spam ) {
		return $is_spam;
	}

	$field_types_to_check = array(
		'text',
		'textarea',
	);

	$text_to_check = array();

	foreach ( $form['fields'] as $field ) {
		// Skipping fields which are administrative or the wrong type.
		if ( $field->is_administrative() || ! in_array( $field->get_input_type(), $field_types_to_check ) ) {
			continue;
		}

		// Skipping fields which don't have a value.
		$value = $field->get_value_export( $entry );
		if ( empty( $value ) ) {
			continue;
		}

		$text_to_check[] = $value;
	}

	if ( empty( $text_to_check ) ) {
		return false;
	}

	$response = wp_remote_post( 'https://ws.detectlanguage.com/0.2/detect', array(
		'headers' => array(
			'Authorization' => 'Bearer your_api_key_here',
			'Content-Type'  => 'application/json',
		),
		'body'    => json_encode( array( 'q' => $text_to_check ) ),
	) );

	if ( is_wp_error( $response ) || wp_remote_retrieve_response_code( $response ) !== 200 ) {
		GFCommon::log_debug( __METHOD__ . '(): $response => ' . print_r( $response, true ) );

		return false;
	}

	$body = json_decode( wp_remote_retrieve_body( $response ), true );
	GFCommon::log_debug( __METHOD__ . '(): $body => ' . print_r( $body, true ) );

	if ( empty( $body['data'] ) || empty( $body['data']['detections'] ) || ! is_array( $body['data']['detections'] ) ) {
		return false;
	}

	foreach ( $body['data']['detections'] as $detections ) {
		foreach ( $detections as $detection ) {
			// Not spam if language is English.
			if ( rgar( $detection, 'language' ) === 'en' && rgar( $detection, 'isReliable' ) ) {
				return false;
			}
		}
	}

	return true;
}

User-Agent

This example shows how you can mark entries as spam based on the User-Agent header sent by the browser used to submit the form.

add_filter( 'gform_entry_is_spam', 'filter_gform_entry_is_spam_user_agent', 11, 3 );
function filter_gform_entry_is_spam_user_agent( $is_spam, $form, $entry ) {
	if ( $is_spam ) {
		return $is_spam;
	}

	$user_agent = rgar( $entry, 'user_agent' );

	if ( empty( $user_agent ) ) {
		if ( method_exists( 'GFCommon', 'set_spam_filter' ) ) {
			$reason = 'User-Agent is empty.';
			GFCommon::set_spam_filter( rgar( $form, 'id' ), 'User-Agent Check', $reason );
			GFCommon::log_debug( __METHOD__ . '(): ' . $reason );
		}

		return true;
	}

	// List of tokens that when found in the user agent will mark the entry as spam.
	$tokens = array(
		'YaBrowser',
		'Yowser',
	);

	foreach ( $tokens as $token ) {
		if ( stripos( $user_agent, $token ) !== false ) {
			if ( method_exists( 'GFCommon', 'set_spam_filter' ) ) {
				$reason = sprintf( 'User-Agent "%s" contains "%s".', $user_agent, $token );
				GFCommon::set_spam_filter( rgar( $form, 'id' ), 'User-Agent Check', $reason );
				GFCommon::log_debug( __METHOD__ . '(): ' . $reason );
			}

			return true;
		}
	}

	return false;
}

Placement

This code can be used in the functions.php file of the active theme, a custom functions plugin, a custom add-on, or with a code snippets plugin.

See also the PHP section in this article: Where Do I Put This Code?

Source Code

As of Gravity Forms 2.4.17 this filter is located in GFCommon::is_spam_entry() in common.php. It was previously located in GFFormDisplay::handle_submission() in form_display.php.