Of Robocalls and Whitelists

[The functionality of these scripts is largely superseded by the AllowList Module]

… of cabbages and kings.

I have several DIDs published for business purposes, and as time passes, they become incrementally more prone to robocalls. This is to the point now that robocalls may well outnumber legitimate calls, with some days being intolerable. The FreePBX blacklist is unable to deal with them effectively because there is no consistency to the Caller ID, nor have I wanted to force all callers to navigate an IVR as it will negatively affect customer experience. And so, not unlike the walrus and the carpenter who lament all the sand on the beach, I’ve complained about robocalls but never did anything about it.

Until a few weeks ago when someone saw fit to wake me up at 5am with an offer to renew my Google listing. This was 5am on a national holiday. A holiday whose only practical purpose is reserved for hangover recovery. And so, with my beauty sleep interrupted, I spent some time writing AGI scripts that will:

  1. check a number against the FreePBX Contact manager and indicate if that number is present or not, and
  2. automatically add a contact to the FreePBX Contact Manager if not already present

With the above in place, I check the inbound Caller ID number against the Contact Manager, and if the number isn’t there, the caller gets sent to an IVR that challenges them with a DTMF entry. Once they successfully pass the challenge, the number is auto added to the Contact Manager, and the caller will never again be sent to the IVR. It’s assumed that no robocalls will get through, but if they evolve I can add some complexity to the IVR such as forcing callers to enter a randomly generated code.

I’m using the third party modue, DynRoutes for the Contact Mgr check, and just a normal Custom Destination to add CallerID to the Contact Manager.

Edit 4 years later

I haven’t thought too much about this thread since moving to use the Allow List module, but I’m revisiting after getting some questions by private message.

Step one is to get these AGI files (or any AGI script) locally on the PBX and getting them in a state that’s usable from asterisk dialplan. I find the easiest way is to login via ssh and running the following commands:

cd /var/lib/asterisk/agi-bin/
wget https://url_to_raw_file/lgaetz-cmcheck.php
wget https://url_to_raw_file/lgaetz-cmadd.php
chown asterisk:asterisk lgaetz-cmcheck.php lgaetz-cmadd.php
chmod +x chmod +x lgaetz-cmcheck.php lgaetz-cmadd.php

To get the download URLs, click the link above to the gists and from there click the “RAW” button to get the plain text version of the script…

The AGIs are now ready to use with Dynamic Routes. To create a Dynamic Route that will check contact manager for the CID number, it would be structured as follows:

To create a dynamic route that you can route a caller thru to automatically add their CID number to Contact Management, it would be structured like this:

9 Likes

As a migratory bird, spam comes in at all hours and I have a similar filter with a few additional features.

Called numbers are automatically added to the whitelist.

W (whitelisted), P (pass) or F (fail) is added to the User field of the CDR, to help troubleshoot incorrectly handled calls.

When first implemented, I used a script to examine the last two years of CDRs, populating the whitelist with all calls that lasted more than a minute and connected to a human.

On calls that fail the IVR challenge, TrueCNAM is used to choose between voicemail and hangup. It drops about half of unwanted voicemails and AFAIK has never disconnected a legitimate caller.

Unfortunately, two manual controls remain: The do-not-disturb button is still needed; calls from friends who don’t know my location or don’t figure the time correctly can come in at any time. A Call Flow Control BLF key temporarily bypasses the filter, needed when calling a large company whose “queue callback” does not present a predictable caller ID (it lights red when on, reminding me to turn it off after receiving the callback).

2 Likes

Can you post yours? Thank you

I can’t easily post a complete solution, because my system updates the whitelist outside of FreePBX, in an app whose primary purpose is displaying recent calls in a small window, with click-to-call functionality.

However, the basic filtering code was posted in [SOLVED]Inbound routing - #9 by gdesilva .

The overall algorithm is described in Can spam call problems really be solved techically? - VOIP Tech Chat | DSLReports Forums .

Ward Mundy made various changes (some of which I don’t agree with) but posted complete code. See Spam Phone Call Blocker and CNAM Caching for FreePBX – Nerd Vittles .

I hope that at least some of the above is useful.

2 Likes

So it turns out I overestimated the ability of some people who call me. I’ve gotten a few who called in, heard a recording telling them to press a button to continue, and they hung up. In order to minimize inconvenience, I thought it would be clever to automatically add all outbound dialed numbers to the white list, easily done using a few lines of custom dialplan:

[macro-dialout-trunk-predial-hook]
exten => s,1,Noop(Entering user defined context [macro-dialout-trunk-predial-hook] in extensions_custom.conf)
exten => s,n,AGI(lgaetz-cmadd.php,${OUTNUM:-10}) ; normalize numbers to 10 digits
exten => s,n,MacroExit
4 Likes