I was editing the contact form on one of my client’s sites today, and was horrified to see the amount of spammy messages coming through their Gravity Forms contact form.
Emails like this:
Or if they’re more clever, they’ll send it from a European female name … as this generates a higher response rate!
Nearly all of this contact form spam is sent from temporary Gmail accounts that will soon be shut down when they get too many spam complaints.
Yes, there is a CAPTCHA on the form, but these messages are submitted by real people, so they fill in the CAPTCHA. There is a strong theme to the messages – nearly all selling cheap SEO and outsourcing services.
Since they have some very common keywords in the messages, such as “outsource”, “SEO” or “Dear Sir/Madam”, I decided to apply a filter to the notifications, so that if the message has one of those spammy keywords in it, then the Gravity Forms notification won’t send to my client.
Unfortunately after a fair bit of time searching, I found that there was no Gravity Forms plugin available to do what I was wanting.
Time for a custom solution.
I found this post from Chris Moore, which provides code that throws a validation error on the forms if someone tries to submit with the spammy keywords.
That was a good start, but since the keyword filter is rather simple, I didn’t want the end user to see that their form hadn’t been submitted. Because they could easily modify the words they think are the cause of the problem and then get it through.
So instead my aim was to have the form seemingly submit successfully, but actually no notification would get sent to the company owner.
So basing my code off what Chris provided here is what I did:
How To Filter For Keywords and Stop Notifications Being Sent with Gravity Forms
- Add a hidden field to my form, called “Passed keyword spam check?” Give it a default value of “YES”
- Edited the notification email to have conditional logic – it will only send if the “Passed keyword spam check?” field has a value of “YES”.
- Now I added this code, modified from Chris’ code, which checks the fields against the range of keywords, and if it finds any of those words, it changes this “Passed keyword spam check” field to “NO”.So the user thinks the form has been submitted successfully, but the notification is not sent. The entry is still stored in the database, but that doesn’t concern me as my clients only deal with the enquiries they receive by email notification.Before we get to the code, there are a couple of points to note about this code. Firstly, as with all custom functions, it should be placed in your functions.php file in your child theme, or in a custom functions plugin.Secondly, there are three things you need to set in the code. These are highlighted in the code as Step 1, Step 2 and Step 3.
- Set the form ID you want this to apply to. gform_pre_submission_1 means form ID 1. gform_pre_submission_2 means form ID 2, etc.
- Choose the keywords you want to block. The example code comes with the words I have chosen to block.
- Finally you need to set the ID of your “Passed keyword spam check” field.
The code defaults to field #7 – on this line:
$_POST['input_7'] = "No";
You can see in the screenshot above that my “Passed keyword spam check” field is Field ID 7. Enter the correct field ID for your form.
Here’s the code:
/* ================================================================== Filter Gravity Forms Submissions for spammy words ================================================================== */ /* * Use an array to search a string * Allows us to pass the stop words list and our post data */ function strpos_arr($haystack, $needle) { if(!is_array($needle)) $needle = array($needle); foreach($needle as $what) { if(($pos = stripos($haystack, $what))!==false) return true; } return false; } /* * Our bad words validation function */ /* -------------------------------------------------------------------------------------- // -------> STEP #1: Enter the ID number of the form you want to check. <------------ */ add_action('gform_pre_submission_1', 'keywords_check'); // The form ID is currently set to ID 1 - shown in the above line gform_pre_submission_1. // If you want to apply it to form ID 2 then change _1 it to _2 // This function will only apply to this form ID you set. If you want to apply this check to other forms you // need to copy the whole function and change the form ID, because we need to specify the field ID below that is your keyword check field. function keywords_check($validation_result){ $form = $validation_result["form"]; /* ----------------------------------------------------------------------------------- // -------> STEP #2: Enter all the keywords that you want to block. <------------ */ $stop_words = array( 'outsource', 'Madam', // this covers all variations of 'Sir/Madam' 'Sir /Madam' 'Sir/ Madam' 'Sir / Madam' etc 'SEO', 'long term relationship', ); $stop_id = array(); foreach($_POST as $id => $post) { if(strpos_arr($post, $stop_words)) { /* * We have a match so store the post ID so we can count it */ $stop_id[] = $id; } } if(sizeof($stop_id) > 0) { $validation_result['is_valid'] = false; /* ----------------------------------------------------------------------------------------- -------> STEP #3: Enter the input number of your keyword checker field. <------------ Note: This is the name of the input not the ID. E.g. input_7 NOT input_1_7 */ $_POST['input_7'] = "No"; } } /* -------------- end of gravity forms filter --------------------- */
If you want to use the check on more than one form on the same site, unfortunately you need to copy the whole function again. Follow these steps:
- Copy the whole function from STEP 1 down to the end
- Change “keywords_check” to a unique name – e.g. “keywords_check2” on both the add_action line and the function line
- Change the form ID in Step 1.
- Change the field ID in Step 3.
If you know how to improve this code so that we don’t have to copy it like this each time, but instead can have an array with the form ID and the field ID (steps 1 & 3), please share!
I hope you find this helpful.