TIPS Custom Inbound Call Screener

Joined
Jun 18, 2014
Messages
13
Reaction score
6
I've implemented this before on vanilla asterisk and want to do it on my shiny new FreePBX:
  • Answer call
  • Generate random number between 1-9
  • Tell user to enter the number they just heard [give 'em three tries than hang up]
  • On entry of correct digit, save CID to db so we don't ask again
  • Then continue routing call normally
In my old system, I just keep a db of DIDs I want to use this behavior and have a GoSubIf at the appropriate place in the dialplan.

I know how to write the code to do this, but I can't figure out just how to implement within FreePBX. I found "Custom Destination" and "Custom Extension", but that's not quite what I need. Any suggestions on how to implement something like this w/in the (otherwise very cozy) confines of FreePBX?
 

rossiv

Guru
Joined
Oct 26, 2008
Messages
2,624
Reaction score
139
You can put the code in extensions-custom.conf in /etc/asterisk. Create a Custom Destination in FreePBX to the context in extensions-custom, and point the Inbound Route to that. You can then point the context back to a subsequent Inbound Route and route however you wish. That be from-trunk,something,s,1 IIRC.

For example:
Call Comes In > Inbound Route > Custom Context in custom > Another Inbound Route > Final Destination.
 
Joined
Jun 18, 2014
Messages
13
Reaction score
6
Thanks - the way this is shaping up in my mind I'd create a custom destination for each extension that needed this feature. Example: My extension is 1000, I create a custom extension 91000 that implements the "robot test", then sends the call to 1000 if they pass. Then point the inbound route to 91000, and presto. I'm going to let that sink in and see if I can think of a better way (the less mucking about I do in vi, the better). Will post code for it when I get the reimplementation working, but here's the rough-n-ready version I had working on the old box:

exten => s,1,NoOp(Check human for ${dnis} ${DB(humancheck/${dnis})})
exten => s,n,Set(c=${CALLERID(number)})
exten => s,n,GotoIf($["${DB(humancheck/${dnis})}" = ""]?humanend)
exten => s,n,GotoIf($[${DB(humans/${c})} != ""]?ok)
exten => s,n,NoOp(Answering call and playing message with random digit)
exten => s,n,Answer()
exten => s,n(begin),Playback(custom/deskoptional-451)
exten => s,n,Set(x=${STRFTIME(${EPOCH},,%S)}))
exten => s,n,Set(x=${x:1:1})
exten => s,n,SayNumber(${x},f)
exten => s,n,Read(y||1)
exten => s,n,GotoIf($[${y} = ${x}]?ok)
exten => s,n,Macro(log,HUMAN test failed (asked for ${x} got ${y}) for ${c} calling ${dnis})
exten => s,n,Goto(begin)

exten => s,n(ok),NoOp(You pass)
exten => s,n,Macro(log,HUMAN test passed for ${c} calling ${dnis})
exten => s,n,Set(DB(humans/${c})=1)
exten => s,n(humanend),NoOp(-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)
exten => s,n,Return

The last time I did this I didn't have FreePBX, so no Asterisk Phonebook came into play: I just had tables in the Asterisk db: HUMANCHECK to list the DIDs I wanted to use the feature, and HUMANS to hold the list of CIDs that had passed the test.

I never realized how many of these dang robocalls I get every day until I migrated my main work line from the old PBX (which has the feature) and my new one (which doesn't). Driving me bonkers with calls purporting to get me on the first page of google, sell me credit card processing machines, et cetera ad nauseum. Am thus motivated and will pound this out this weekend.
 

john p

Member
Joined
Jul 9, 2013
Messages
82
Reaction score
6
FYI, I had the same concern but I just routed all incoming calls to an IVR that passed calls to my local routing process after any keypress but hangs up if no keypress before timeout. Simpler but does not save "good" callers for next time. It has, so far (~20 months), completely killed robocalls. Just an alternative.
 
Joined
Jun 18, 2014
Messages
13
Reaction score
6
Ok, here's the 1.0 version of this. It works, but I want to change it to use just one table instead of two. I decided midway through I wanted a record of proven robots. Better way to do this is one table with a status bit (0=human, 1=robot) but this does at least work.

Following my example, extension 1000 (me, as it happens) has a parallel in the robotfilter context that looks like this. It executes robotcheck and then hangs up on the caller if it doesn't get what it wants. The inbound route for my main number is pointed here, and I'd just add more 9xxxx extensions in this context for each user that wanted the functionality. I've tried to minimize the things I do in this pbx that require command-line skillz to admin, but this feature was worth violating that principle.

[robotfilter]
exten => 91000,1,Macro(robotcheck,s,1)
exten => 91000,n,ExecIf($["${ROBOT}"="0"]?Goto(ext-group,1000,1):HangUp())

And here's the guts:

[macro-robotcheck]
; ROBOT is true until proven otherwise, TRIES is how many tries/timeouts have occurred, C is the callerid
exten => s,1,Set(ROBOT=1)
exten => s,n,Set(TRIES=0)
exten => s,n,Set(TODAY=${STRFTIME(${EPOCH},,%d%m%Y-%H:%M:%S)})
exten => s,n,Set(c=${CALLERID(number)})

; If this caller has already proved they're not a robot, skip this whole thing
exten => s,n,GotoIf(${DB_EXISTS(notrobots/${c})}?ok)

; Otherwise, answer the phone and play a random digit, increment the TRIES counter, wait for response or timeout
exten => s,n,Answer()
exten => s,n(begincheck),Playback(deskoptional-451)
exten => s,n,Set(x=${STRFTIME(${EPOCH},,%S)}))
exten => s,n,Set(x=${x:1:1})
exten => s,n,SayNumber(${x},f)
exten => s,n,Read(y,,1)
exten => s,n,Set(TRIES=$[${TRIES} + 1])

; If they make too many tries/timeouts, they're a robot
exten => s,n,GotoIf($["${TRIES}"="3"]?humanend)
; If the digit matches, go to 'ok', otherwise let them try again
exten => s,n,GotoIf($["${y}"="${x}"]?ok:begincheck)

; If we get here, they're not a robot. Make the appropriate entries in the db
exten => s,n(ok),Set(ROBOT=0)
exten => s,n,Set(DB(notrobots/${c})=${TODAY})
exten => s,n,DbDel(robots/${c})

; If we got this far, make a note in the db if they're a robot
exten => s,n(humanend),ExecIf($["${ROBOT}"="1"]?Set(DB(robots/${c})=${TODAY}))
 

Members online

No members online now.

Forum statistics

Threads
25,810
Messages
167,755
Members
19,240
Latest member
nikko
Get 3CX - Absolutely Free!

Link up your team and customers Phone System Live Chat Video Conferencing

Hosted or Self-managed. Up to 10 users free forever. No credit card. Try risk free.

3CX
A 3CX Account with that email already exists. You will be redirected to the Customer Portal to sign in or reset your password if you've forgotten it.
Top