Clearing out support desk spam after Christmas

I use Freshdesk for support email ticketing and user forums. Whilst I’m generally happy with the solution (standalone hosted forums seem very expensive elsewhere, and I have a price plan which is no longer generally available) it’s spam filtering is quite woeful. The response from their customer support to dealing with the type of spam I’ve been getting is to setup a custom rule to automatically mark and delete items containing specific characters - and this requires frequent updating.

After some time off over Christmas (much of which was spent feeling unwell) I fired up Freshdesk to see 27 pages of mostly spam. The process of clearing the spam needs you to review each page, select those messages which are spam and then choose to delete them.

Thankfully Freshdesk has an easy to use API which is well documented at

The spam in question contains Cyrillic characters in the subject line. In Unicode Cyrillic characters are in the range 0400 to 04FF.

My approach was to write a script to:

  1. Get a list of tickets (this is about 30 at a time).
  2. Put each ticket where the subject line contains three or more characters with a probable Cyrillic character into a list of tickets to delete.
  3. Delete those tickets.
  4. Repeat until there are no tickets to be deleted.

I used Python and the amazing Requests library. Here is the resulting script (with my Freshdesk API token and domain removed):

#!/usr/bin/env python3

import requests
from requests.auth import HTTPBasicAuth

# Add your own Freshdesk API key and set the domain correctly below
api_key = 'xxx'
base_url = ''

def delete_ticket(id):
    requests.delete(base_url + '/tickets/' + str(id), auth=HTTPBasicAuth(api_key, 'X'))

def is_invalid(subject):
    return len(list(filter(lambda x: 1024 <= x <= 1279, [ord(c) for c in subject]))) > 3

def fetch_and_delete_tickets():
    print('Fetching next batch of tickets...')
    tickets = requests.get(base_url + '/tickets', auth=HTTPBasicAuth(api_key, 'X')).json()
    tickets_to_delete = []
    for ticket in tickets:
        if is_invalid(ticket['subject']):
    print(f'Deleting {len(tickets_to_delete)} tickets from {len(tickets)} tickets...')
    for ticket in tickets_to_delete:
        print('Deleting ticket...')
    if len(tickets_to_delete) > 0:


I’ll be sure to keep this script handy for further spam attacks - much time and frustration saved.