Spam protection is never perfect. Some junk contacts will still get into CiviCRM. First thing is to stop the spam, and then clean up your CRM afterwards.
One easy cleanup trick is to use SearchKit with regex to find names that look machine-generated:
^(?=.*[a-z])(?=.*[A-Z])[A-Za-z]{15,}$
That looks for a first or last name that is:
- 15+ letters
- letters only
- contains both upper and lowercase characters
For example:
QwErTyUiOpAsDfG
I run that against First Name OR Last Name, review the results, then delete the obvious junk.
If your forms create an Activity for each submission, you can narrow the search further by adding a With (required) join to Contact Activities. That way, you are reviewing suspicious contacts that also came through one of your form workflows.
You can import this SearchKit search directly:
[
[
"SavedSearch",
"save",
{
"records": [
{
"name": "Contact_Spam",
"label": "Contact Spam",
"api_entity": "Contact",
"api_params": {
"version": 4,
"select": [
"id",
"sort_name",
"contact_type:label",
"contact_sub_type:label"
],
"orderBy": [],
"where": [
[
"OR",
[
[
"first_name",
"REGEXP",
"^(?=.*[a-z])(?=.*[A-Z])[A-Za-z]{15,}$"
],
[
"last_name",
"REGEXP",
"^(?=.*[a-z])(?=.*[A-Z])[A-Za-z]{15,}$"
]
]
]
],
"groupBy": [],
"join": [],
"having": []
},
"description": "Find suspicious contacts with long mixed-case names"
}
],
"match": [
"name"
]
}
]
]
This won’t catch every spam contact, but it matches the pattern I’ve been seeing lately. The goal is to make the obvious junk much faster to find and clean up.
