Possible to do this with incoming calls?

Wondering about dealing with incoming callers. We get a LOT of sales/nuisance calls which drain us and hoover up time and energy. I have devised in my head an ideal call flow, but not sure how I’d achieve it.

Is it possible to do this?

Incoming call

Check against CallerID superfecta

→ a) Caller NOT known to be spam, but NOT known to be not spam either. Directed to a Turing test. If call passes turing test, added to ‘safe’ list, → sent to extension. If it fails, call hangs up, but caller free to ring again and attempt Turing test again whenever.
→ b) Caller shares same area code as the region I live in, if it’s prefixed ‘020’ (i.e. London), deemed to be safe. → Rings at extension.
→ c) Caller found on our internal list of customers we DO want to hear from. → Rings at extension.
→ d) CallerID Superfecta deems the call to be spam. Or dangerous. Or harassing. OR it’s found on our internal list of sales callers we don’t want to hear from. → Sent to Lenny.

Is this something we could do with Caller ID superfecta or another FreePBX module? Appreciate this is a lot of ask for an out of the box solution and that one may not exist. On the other hand, FreePBX continues to impress with its versatility!


Whitelist/robocall block here: Of Robocalls and Whitelists

Turing test: Random IVR code

I don’t know how it is in England or the EU but spammers in the US use local area codes (regions) to spoof they are calling from an area/region you would expect calls from and thus not ignore. So just keep that in mind.

1 Like

These are my nemesis.

If the number is not recognized, try adding


Before ‘making a noise’ yourself . Real people say something many robocalls hangup as they themselves WaitForNoise.

If getting, noise, if the noise is more than a few seconds, it’s also likely a robocall. So then WaitForSilence() before continuing

Hi Lorne,

Thanks for those, I can see there is the makings of a randomised turing test and a way to check callers against a list and if they’re not on the list, make them take the turing test, and then permanently whitelist them.

I was wondering if it was possible to do exactly that, but with the caveats:

  • If caller shares my e.g. ‘020’ prefix of London, they don’t need to take the test, whether they are on the list or not.
  • Use callerID superfecta so that known spammers don’t even get the option of taking the test, they’re just binned straight away or sent to Lenny.

Is THIS also doable/possible, or is this just getting a bit TOO involved?

Thanks ! :slight_smile: :slight_smile:

All possible, but you may find there are diminishing returns to your efforts.

Create an inbound route with a CID filter of _0020XXXX or whatever to match CID. Note the leading underscore, then you can direct these calls to an alternate destination.

Yes the Superfecta spam intercept happens ahead of the inbound routes, so throwing that into the mix will prob work as expected.

For me over on the left side of the Atlantic, the vast majority of my unsolicited calls are robots, and are stopped by a simple IVR and ‘press any button to continue’. So far this calendar year, 2 non-robots got thru, but I’m blocking a handful of bots a day. I don’t consider it worthwhile (yet!) to go to any greater lengths.


Hi Lorne

Thanks very much. I think/hope in the UK at the moment, it should work pretty well. NONE of the spam calls I currently get originate from my area code (so in that respect I guess our telespammers are not as smart as US ones…yet). However, most are human and based in places like India (and not robots). So I think for me, an turing test will only be so effective. I am hoping they just hang up when faced with one.

I must admit while I’ve got most of the constituent parts of your solution working, I’m having a spot of trouble stitching it all together. What I’ve ‘achieved’ :-

  • I’ve got the local area inbound route working, and can potentially send callers with my local area code to a different inbound route
  • I’ve installed the two scripts cmadd and cmcheck, and they are both working, in that dialled numbers are added to contact manager and incoming numbers are too.
  • I’ve added bender-blocker to /etc/asterisk/extensions_custom.conf


  • I have nothing in dynamic routes as I wasn’t sure what to add!
  • I have three ‘custom destinations’ setup, but they’re not setup correctly ( see screenshots below )

I’m nearly there, but I’m just struggling a little bit with the “links” between what I’ve installed. I’m sorry if I missed the instructions for setting up the dynamic route etc!




Finally I guess I wonder what the difference is between ‘contact manager’ and the asterisk phonebook.


@lgaetz I’ve made good progress! I’m NOT using DynRoutes as you were, but instead I’ve bodged it together like this - tell me if I’ve misunderstood and this is actually not a good idea.

Starts with an…
Inbound Route -> Custom destination: Check phone number against whitelist

exten => s,1,Noop(Entering user defined context [check-whitelist] in extensions_custom.conf)
exten => s,n,AGI(lgaetz-cmcheck.php,${CALLERID(number)})
exten => s,n,gotoif($["${whitelist}"="false"]?app-announcement-1,s,1)
exten => s,n,Return

Announcement plays a recording to tell the caller to enter digits…
Then your custom destination: robocall turing test.

exten => s,1,Noop(Entering context bender-blocker in extensions_custom.conf)
exten => s,n,Answer
exten => s,n,Set(Count=0)
exten => s,n(restart),set(goal=${RAND(0,9)}${RAND(0,9)}${RAND(0,9)}${RAND(0,9)}) ; generates a 4 digit number, modify as req'd
exten => s,n,SayDigits(${goal})
exten => s,n,Read(dtmf-in,,${LEN(${goal})},,,10)   ; 10 second timeout, modify as req'd
exten => s,n,execif($["${dtmf-in}"="${goal}"]?Return)      ;  if input matches, send back to FreePBX

; give caller multiple chances
exten => s,n,Set(Count=$[${Count}+1])
exten => s,n,gotoif($["${Count}"="3"]?finish)   ; bail after 3rd attempt
exten => s,n,Playback(challenge_try_again)      ; sub your own recording
exten => s,n,goto(restart)

; what do you want to do with calls that fail?
exten => s,n(finish),hangup

Crucially, the Custom Destination is set to return to an extension.

Yeah, that all looks good. Dynroutes allows for more to happen in the GUI but custom destinations work fine too.

I whitelist all outbound numbers called, and all CIDs that pass the Turing test.

Probably not necessary now, but for completeness, here is a sample config of using Dynroutes with an AGI for this:

which results in these full log lines

-- Executing [902<redacted>@from-pstn:24] Goto("PJSIP/fpbx-1-8CeeToemYCth-00000020", "dynroute-1,s,1") in new stack
-- Goto (dynroute-1,s,1)
-- Executing [[email protected]:1] AGI("PJSIP/fpbx-1-8CeeToemYCth-00000020", "lgaetz-cmcheck.php,1920<redacted>") in new stack
-- Launched AGI Script /var/lib/asterisk/agi-bin/lgaetz-cmcheck.php
-- lgaetz-cmcheck.php,1920<redacted>: Searching all Contact Mgr groups for 1920<redacted>
-- lgaetz-cmcheck.php,1920<redacted>: Found 1920<redacted> in Contact Mgr
-- lgaetz-cmcheck.php,1920<redacted>: Setting Asterisk channel var whitelist to true
-- <PJSIP/fpbx-1-8CeeToemYCth-00000020>AGI Script lgaetz-cmcheck.php completed, returning 0
-- Executing [[email protected]:2] Set("PJSIP/fpbx-1-8CeeToemYCth-00000020", "dynroute=true") in new stack
-- Executing [[email protected]:3] GotoIf("PJSIP/fpbx-1-8CeeToemYCth-00000020", "0?dynroute-1,1,1") in new stack
-- Executing [[email protected]:4] GotoIf("PJSIP/fpbx-1-8CeeToemYCth-00000020", "1?from-did-direct,5003,1") in new stack
-- Goto (from-did-direct,5003,1)
-- Executing [[email protected]:1] GotoIf("PJSIP/fpbx-1-8CeeToemYCth-00000020", "1?ext-local,5003,1:followme-check,5003,1") in new stack
-- Goto (ext-local,5003,1)
1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.