Tropo is part of CiscoLearn More

Adding Voicemail Detection to an Outbound Tropo Application

Posted on November 30, 2015 by Phil Bellanti

One of the most useful features for outbound voice call applications is “Call Progress Analysis” (CPA) which can detect whether the call was answered by a human or an answering machine/voicemail system.  Incorporating CPA-based logic in a Tropo application script can allow it to perform different functionality based on if a human or voicemail system answered the call. For example, if the outbound call is detected as answered by a HUMAN, the app can continue with the intended prompts and collect input from the end-user as normal. However, if the outbound call is detected as being answered by a MACHINE (voicemail system or answering machine), it can have some different logic to play a custom audio file specifically for voicemail or to retry the outbound call after a period of time.

How It Works…

This is accomplished using the machineDetection parameter in the call() method. When this function is implemented, the returned object will have the userType property, which returns ‘HUMAN’, ‘MACHINE’, or ‘NIL’ and can be accessed through event.value.userType ($event->value->userType if using PHP). It’s worth noting machineDetection can also return ‘FAX’ as the userType, but since this has become an extreme edge-case in recent years, it wasn’t even incorporated in this particular demo. The userType ‘NIL’ can occasionally pop up on calls answered with a lot of background noise, complete dead silence, or by a non-standard answering machine.  Here in the demo, we’re treating ‘NIL’ calls as answered by MACHINE, however there’s an added step in the application to give people a chance to identify as HUMAN, by requesting them to press ‘1’ before a message geared towards a voicemail system is played. This step also helps eliminate any initial false-positive detections of MACHINE that may arise in an outbound campaign. This demo application is written in Ruby, using Tropo’s Scripting API and can be hosted right on our cloud platform for you.   In case you haven’t already, you’ll first want to register for a free developer account on From there, follow the steps to create an application as detailed here.  The full demo application script can be found on GitHub.


Application Walkthrough

The first part of the script is run when the userType ‘MACHINE’ is returned. In this block, we are further enhancing the machineDetection feature by asking for confirmation in case the call was actually answered by a human (falsely detected as MACHINE), by prompting the end-user to press ‘1’ to hear the message now. Obviously, a machine or voicemail system would ignore that question and the timeout will be triggered. This will take us to lines 15-22, where the application waits for silence after a beep tone. This part is certainly not required for machineDetection, but can help the accuracy when reaching unconventional voicemail machines.

def ask_vm (user)
	ask "Press one at any time to hear your message, or stand by and it will begin momentarily", {
		:timeout => 2,
		:choices => "1",
		:mode => "dtmf",
		:voice => "Tom",
		:onChoice => lambda {|event|
			user = "HUMAN"
			human_answer(user) },
		:onTimeout => lambda {|event|
			vm_answer(user) }}

def beep_listen ()
	record ".", {
		:beep => false,
		:timeout => 1,
		:silenceTimeout => 1,
		:maxTime => 15,
		:terminator => "#" }

The functions in lines 24-32 are run when the userType is returned as ‘HUMAN’. Here, we are asking the end-user if they want to opt-out of future messages, but this can be modified to whatever logic you want to perform when a HUMAN answers the call. Lines 35-38, will be run on calls only when all of the following occur:

  1. The initial userType was detected as ‘MACHINE’.
  2. A timeout on Line 2 was triggered (when the prompt to press ‘1’ is ignored).
  3. The beep and silence was detected from a voicemail system.

Again, 2 and 3 were added in the application just as enhancements to the built-in detection, essentially to help identify irregular voicemail systems with more unique qualities.

def human_answer (user)
	log "value returned from the machine detection  ==  " + user
	say $message , {:voice => "Tom"}
	ask "to opt out of future reminders, please press 1", {
		:choices => "1",
		:mode => "dtmf",
		:voice => "Tom" }
	say "Thank you, good bye" , {:voice => "Tom"}

def vm_answer (user)
	log "value returned from the machine detection  ==  " + user
	say $message , {:voice => "Tom"}

The settings for the outbound call and logic for machineDetection is in the last portion of code, lines 41-59. The callerID configuration is done in line 42, which sets the phone number to be sent and displayed at the destination being called. This app is using $numberToDial as the variable name to pass in the destination phone number parameter. This is sent along with the token-string to Tropo’s REST API when launching the application. You can find more information on passing in custom parameters to a Tropo application here.

call $numberToDial , {
	:callerID => "14072420001",
	:timeout => 60,Tom
	:machineDetection => {"introduction" => "Hello...", "voice" => "Tom" },
	:onAnswer => lambda {|event|
		if event.value.userType.nil?
			log "This was NIL   "
			user = "MACHINE"
			user = event.value.userType
		if user == "HUMAN"
		end	}}



Leave a Reply