A buddy of mine at Cisco is truly a genius when it comes to thinking outside the box. He loves technology and hates annoying telemarketers. Over time, he developed a call management system that involves a combination of open source software and proprietary hardware. He took advantage of the numerous application programing interfaces (API’s) available to create a tightly integrated environment.
One of the solutions delivered attempts to mimic artificial intelligence. As incoming calls are received, the system compares the associated Caller ID against a configured white list. If the Caller ID exists, all home phones immediately ring as one would expect. However, if the Caller ID is not recognized, a Text-to-Speech (TTS) based message is played to the caller.
If by chance a family member, friend or other acquaintance happens to call from a previously unknown number, the system offers an option to ring through to all home phones simply by pressing the digit one. Only a single situation has been experienced where an actual telemarketer had the audacity of pressing one. All other unwanted humans or automated systems have immediately hung up. The good news is… all home phones remain silent during the automated screening process.
A text based log of all calls received is kept and even the audio of each call is recorded. This is useful for validating call attempts and to determine if any of the unknown Caller ID’s should be added to the white list.
It’s not uncommon to receive repeat calls from the same Caller ID, such as those initiated by automated dialers. When repeat calls such as these are detected, a bit of interrogation is performed to identify the caller. In some cases the call might have simply been an automated announcement stating the trash won’t be picked up on Monday due to the holiday. This is easily learned from the audio recording.
If the Caller ID is determined to be from a friendly source, it’s easily added to the white list. However, if the repeat caller is identified to be a telemarketer, survey taker, etc., the system is configured to present Special Information Tones (SIT). You’ve all heard that before. “Do…do…do… The number you have called has been disconnected…” In some cases, the caller or dialer involved is smart enough to remove the called number from the outbound campaign when detecting the SIT. If playing the SIT does not do the job, the Caller ID is then pointed to what follows.
Here’s how repeat callers are handled by this system. Also provided is a bit of insight of what’s going on under the hood.
A Fun Telemarketer Solution
The repeat calls described above are directed to and answered by an Interactive Voice Response (IVR). The IVR attempts to mimic a human rather than simply presenting an obvious recording. It does so by listening for speech and periods of silence prior to responding. While not perfect, it works pretty well.
The audio played is presented in an order that attempts to follow most telemarketer dialog flows. So when a telemarketer calls trying to sell something, it mimics an expected response and prompts the Telemarketer to keep going with their pitch. As the conversation happens, it becomes annoying (by design) and eventually hangs up on the Telemarketer.
Example walkthrough of me calling this and pretending to be a telemarketer
- SYSTEM: Hello there (elder man voice)
JOEY: Hello, my name is Joey and I want to offer you the deal of a lifetime.
SYSTEM: Sorry I can barley hear yea.
JOEY: Its ok, my name is Joey and I want to offer you the deal of a lifetime
SYSTEM: YES YES yes ….
JOEY: For 10 dollars a month, I’ll email you happy thoughts … just 10 dollars a month
Oh good Yes yes yes
JOEY: And wait there’s more, actually there isn’t
SYSTEM: Somebody called about the same thing last week. Was that you?
JOEY: Possibly could have been me or one of my partners.
SYSTEM: Sorry what’s your name again ?
JOEY: Its Joey
SYSTEM: It’s funny that you should call because my 3rdeldest Merissa was just talking about this week. She is very smart .. the first of the family to go to university … so um … so I should look into this sort of. What more can you tell me about this sort of thing
JOEY: Well its simple, you pay me 10 dollars a month and I email you happy things.
SYSTEM: Which,company are you calling from again?
JOEY: Happy thoughts.com
SYSTEM: Here is the thing, the last time somebody called up, I got in a lot of trouble for buying something I should have not. My eldest wouldn’t speak to me for a week, and that really hurt. And sometimes in family these things are important.
JOEY: Its only 10 dollars a month and you will be a lot happier.
SYSTEM: Well you know, since you put it that way, you have been quite straight forward with me … hello …… hello are you there
JOEY: Yes I’m still here
SYSTEM: Sorry I have a problem with this phone and my hearing so good. Sorry what were you saying again?
JOEY: All you need to do is setup an account
SYSTEM: With finances, I can’t spend as much as I should. How does this work?
JOEY: You just give me a credit card number and I’ll start charging it.
SYSTEM: You have been patient with a old man here, my third eldest Merissa .. says I should be going forward and … DUCK SOUNDS QUACKING … wait sir can you hold on for a second …. Sorry what where you saying there again? SYSTEM HANGS UP
Let’s face it, nobody wants to be bothered by unwanted telemarketers, charity organizations and such. So why not have a bit of fun with them… and even record the audio for some additional playback entertainment. I had fun speaking with this system and it does really feel like I’m talking with a elderly person. I can imagine the crazy recordings my buddy has captured using this tactic.
There are many parts to this system however here’s a small snippet from the associated Asterisk dial plan. The 8888217082 number reflects an offending telemarketer’s Caller ID. This number was pointed to an Asterisk dial plan context called “myrobot”.
exten => s,n,GotoIf($[“${CALLERID(number)}” = “8888217082”]?myrobot,659,1)
Here’s the actual myrobot dial plan context.
- [myrobot]
- exten => 659,1,Answer
- ; Valid MixMonitor Options: Just dial plan syntax reminder notes for me.
- ; b – Only save audio to the file while the channel is bridged. *does not include conferences*
- ; a – Append to the file instead of overwriting it.
- ; v(<x>) – Adjust the heard volume by a factor of <x> -4/4.
- ; V(<x>) – Adjust the spoken volume by a factor of <x> -4/4.
- ; W(<x>) – Adjust the overall volume by a factor of <x> -4/4.
- exten => 659,n,MixMonitor(/etc/asterisk/gk-cdr/${UNIQUEID}#${CALLERID(num)}#MY ROBOT.gsm,v(1)V(1))
- exten => 659,n,Set(TIMEOUT(absolute)=600)
- exten => 659,n,Set(MACHINE=0)
- exten => 659,n,Set(OPTION=5)
- exten => 659,n,Set(TALK_DETECTED=0)
- exten => 659,n,Gosub(playit(robot01))
- exten => 659,n,Gosub(playit(robot02))
- exten => 659,n,Gosub(playitonce(robot03))
- exten => 659,n,Gosub(playitonce(robot04))
- exten => 659,n,Gosub(playitonce(robot05))
- exten => 659,n,Gosub(playitonce(robot06))
- exten => 659,n,Gosub(playitonce(robot07))
- exten => 659,n,Gosub(playitonce(robot12))
- exten => 659,n,Gosub(playitonce(robot13))
- exten => 659,n,Gosub(playitonce(robot14))
- exten => 659,n,Gosub(playitonce(robot15))
- exten => 659,n,Gosub(playitonce(robot16))
- exten => 659,n,Hangup
- exten => 659,n(playit),NoOp(robot speaks and repeats until response received)
- exten => 659,n,Set(LOCAL(robotclip)=${ARG1})
- exten => 659,n(oncemo),Set(TALK_DETECTED=0)
- exten => 659,n,Background(myrobot/${robotclip})
- exten => 659,n,AMD(2500,1500,800,5000,100,50,3,256)
- exten => 659,n,NoOp(${AMDCAUSE})
- exten => 659,n,GotoIf($[“${AMDCAUSE:0:17}”=”INITIALSILENCE-25”]?reststop)
- exten => 659,n(mach),WaitForSilence(700,3)
- exten => 659,n,Goto(humn)
- exten => 659,n(reststop),WaitForSilence(800,2)
- exten => 659,n,Goto(oncemo)
- exten => 659,n(humn),Return
- exten => 659,n(playitonce),NoOp(myrobot speaks once)
- exten => 659,n,Set(LOCAL(robotclip)=${ARG1})
- exten => 659,n(noresponse),Background(myrobot/${robotclip})
- exten => 659,n,AMD(2500,1500,800,5000,100,50,3,256)
- exten => 659,n,NoOp(${AMDCAUSE})
- exten => 659,n(mach2),WaitForSilence(2000,1)
- exten => 659,n(humn2),Return