Speech recognition grammar object

class HighLevelGrammar

This class is used with the capture_input function.

The Grammar class represents a textual representation of grammars for use in speech recognition. The grammar defined here is used by Aculab Cloud speech recognition to determine what to listen for and, therefore, defines what a user may say.

The grammar can have a maximum of 2000 characters, but it should be kept simple to ensure a good recognition rate. The accuracy can be optimised by careful programming: designing the grammar to avoid confusable words, and prompting the caller in such a way as to ensure they respond in line with that grammar.

Optional argument:
  • formatted_grammar:

    A grammar string that defines what the speech recognition will listen for.

The argument formatted_grammar, if provided, must adhere to the grammar rules:

The Speech Grammar Format:

  • All grammars must end with a semicolon.

  • The most basic grammar instructs the speech detector to listen for a single word, for example, door; will recognise the word door.

  • A sequence of words can be given, shut the door; will recognise that sequence of words.

  • Square brackets can be used to make a word optional, so, [please] shut the door; will recognise the sequence with or without the please.

  • The pipe symbol can be used to provide alternatives, door | gate; will recognise the word door or the word gate.

  • Round brackets can be used to group words and rules together, so, shut the (door | gate); will recognise “shut the door” or “shut the gate”; whereas, without the round brackets, shut the door | gate, will recognise the phrase “shut the door” or the single word “gate”.

Putting these rules together we can make, [please] shut the (door | gate);.

Capital letters are allowed but results will always be lower case. The non-alphabet characters permitted in words are: apostrophe, full stop (period), hyphen and underscore.

For more grammar rule options and examples please see the online documentation.

Usage example:

from prosody.uas.highlevel import HighLevelGrammar

my_grammar = HighLevelGrammar('yes [please] | no [thanks];')
create_from_alternatives(*alternatives)

Create a formatted grammar string from an array of alternatives.

Required argument:
  • alternatives:

    The alternative strings to listen for.

Usage example:

# this example will create the grammar 'yes | no | maybe;'
my_grammar = channel.SpeechDetector.Grammar()
my_grammar.create_from_alternatives('yes', 'no', 'maybe')
create_from_predefined(predefined)

Several pre-defined grammars are available for you to use. Please check the website for more options.

Examples:
  • OneDigit

    To recognise a single digit, zero to nine.

  • TwoDigits

    To recognise two digits, zero to nine.

  • ThreeDigits

    To recognise three digits, zero to nine.

  • FourDigits

    To recognise four digits, zero to nine.

  • FiveDigits

    To recognise five digits, zero to nine.

  • OneToThirtyOne

    To recognise a single number, one to thirty one.

  • SixteenToNinetyNine

    To recognise a single number, sixteen to ninety nine.

  • ZeroToNinetyNine

    To recognise a single number, zero to ninety nine.

Usage example:

my_grammar = channel.SpeechDetector.Grammar()
my_grammar.create_from_predefined('OneDigit')

Speech recognition digit options

class HighLevelDigitInputOptions

This class is used with the capture_input function.

This is a configuration class for setting digit options when doing speech recognition in combination with digit recognition.

Optional arguments:
  • valid_digits

    The string of valid digits. By default the set of valid digits is 0 to 9.

  • digit_count

    The number of digits that will make up the number. Default is 0, no limit.

  • dtmf_end_digit

    A digit from the set ‘0123456789#*’. This must not be the same as the help digit - which is not set in this class. Default is ‘#’.

  • seconds_digit_timeout

    The number of seconds to wait for a digit input. Default is 5.

Usage example:

# Specify the valid digits.
from prosody.uas.highlevel import HighLevelDigitInputOptions
my_digit_input_options = HighLevelDigitInputOptions(valid_digits='12345')

The high level call channel

class HighLevelCallChannel

The high level channel API is supplied to make it easier to write applications that perform certain common tasks. It comes as a HighLevelCallChannel class that can be used to wrap a channel object and provide additional functions.

The HighLevelCallChannel wrapper can, for instance, be used to quickly create an IVR menu system or automate the process of connecting an incoming call to a new outbound call.

The high level channel API automates a lot of the complexity of some common tasks and also provides default behaviour that will suit most users. Thus turning a task that might otherwise require a few dozen lines of application code into just one or two lines.

To use this class it must first be imported:

from prosody.uas.highlevel import HighLevelCallChannel

Usage example:

from prosody.uas import Hangup, Error
from prosody.uas.highlevel import HighLevelCallChannel

def main(channel, application_instance_id, file_man, my_log, application_parameters):
    high_level_channel = HighLevelCallChannel(channel, my_log)

Once the channel has been wrapped in this way, additional high level functions become available on the new object. All functions and attributes that would normally be available on the channel object are also available on the new high level object.

Please note that the high level channel API is still in beta and may change.

class CapturedInput(input_type, captured_input)

This class is used with the capture_input function.

This is the results class for capture_input. This class will contain the type of the captured input - which can be SPEECH or DIGITS - and the captured input itself, which will be a string of words or digits.

Please see the captured input function for a usage example.

call_and_connect(other_call, call_to=None, call_from='', seconds_timeout=120)

Connect two calls together. Optionally place an outgoing call prior to connecting.

The current call (the one invoking this function) will normally be an inbound call, other_call will be an outbound call. The other_call may already be connected, or it may still need to be placed.

Required argument:
  • other_call

    a reference to the outbound channel to which the current call is to be connected.

Optional arguments:
  • call_to

    the outbound call destination. Default is None.

  • call_from

    the origin of the outbound call. Default is ‘’.

  • seconds_timeout

    time allocated to make the outbound call. Default is 120.

This is the high level function that will invoke a full-duplex connection between the lines owned by two active calls.

The other_call can be an IDLE channel. If it is, this function will place an outbound call on the channel using the call_to and call_from parameters. If the other_call has already been placed and is in CALL_OUTGOING state or further, then call_from and call_to do not have to be provided.

The current call does not have to be in ANSWERED state when this function is called, but it does have to be progressing.

If the current call isn’t ANSWERED, this function will place ringing on the current call (if it is an inbound call) when the other_call is in RING_OUTGOING state; and it will answer the current call once the other_call is in ANSWERED state.

Once both calls are in ANSWERED state the lines will be connected.

If seconds_timeout is not None, a timeout will apply for making and connecting the calls. The function will return False if the timeout is reached and the calls have not been connected. The default timeout is 120 seconds. A timeout will not affect the state of the calls.

If the current call state goes to IDLE this function will raise a Hangup exception and the other call will be hung up.

If the other call state goes to IDLE and the current call is not ANSWERED, the current call will be rejected with the cause provided by the other call, and the function will return False.

If the other call state goes to IDLE and the current call is ANSWERED, the function will return False without affecting the current call.

For details on specifying the call_to and call_from parameters for PSTN or SIP destinations please see the online documentation for outbound calls.

This function will block until the calls have been connected, the timeout has been reached, or either of the call states has returned to IDLE.

This function will return True on success, else False.

Usage example:

from prosody.uas.highlevel import HighLevelCallChannel

def main(channel, application_instance_id, file_man, my_log, application_parameters):
    out_channel = channel.ExtraChannel[0]

    high_level_channel = HighLevelCallChannel(channel, my_log)
    if high_level_channel.call_and_connect(out_channel, call_to='sip:fred@127.0.0.1:5060;user=phone') is False:
        raise Hangup('Connect to outbound call failed')

    # the calls are connected, carry on
call_and_connect_to_conference(other_call, conference_room_name, talker_and_listener=True, conference_lifetime_control=None, conference_party_media_settings=None, seconds_timeout=120)

Connect a call to a conference.

The current call (the one invoking this function) will normally be an inbound call, other_call will be an outbound call call channel.

The other_call must not already be connected.

Required argument:
  • other_call

    a reference to the outbound channel to which the current call is to be connected.

  • conference_room_name

    the name of the conference room to which to add this party.

Optional arguments:
  • talker_and_listener:

    whether the party is allowed to talk, as well as listen, in the conference. Default is True.

  • conference_lifetime_control:

    whether the conference should start when this party enters.

  • conference_party_media_settings:

    file and TTS play options, mute options.

  • seconds_timeout

    time allocated to make the outbound call. Default is 120.

This is the high level function that will invoke a full-duplex connection between the lines owned by two active calls.

The other_call must be an IDLE channel. This function will place an outbound call on the channel using the conference_room_name parameter.

The current call does not have to be in ANSWERED state when this function is called, but it does have to be progressing.

If the current call isn’t ANSWERED, this function will place ringing on the current call (if it is an inbound call) when the other_call is in RING_OUTGOING state; and it will answer the current call once the other_call is in ANSWERED state.

Once both calls are in ANSWERED state the lines will be connected.

If seconds_timeout is not None, a timeout will apply for making and connecting the calls. The function will return False if the timeout is reached and the calls have not been connected. The default timeout is 120 seconds. A timeout will not affect the state of the calls.

If the current call state goes to IDLE this function will raise a Hangup exception and the other call will be hung up.

If the other call state goes to IDLE and the current call is not ANSWERED, the current call will be rejected with the cause provided by the other call, and the function will return False.

If the other call state goes to IDLE and the current call is ANSWERED, the function will return False without affecting the current call.

This function will block until the calls have been connected, the timeout has been reached, or either of the call states has returned to IDLE.

This function will return True on success, else False.

Usage example:

from prosody.uas.highlevel import HighLevelCallChannel

def main(channel, application_instance_id, file_man, my_log, application_parameters):
    out_channel = channel.ExtraChannel[0]

    high_level_channel = HighLevelCallChannel(channel, my_log)
    if high_level_channel.call_and_connect_to_conference(out_channel,
                                                         conference_room_name='my_conference') is False:
        raise Hangup('Connect to conference failed')

    # the calls are connected, carry on
call_inbound_service_and_connect(other_call, call_to=None, call_from='', seconds_timeout=120)

Connect a call to another inbound service. Optionally place an outgoing call prior to connecting.

The current call (the one invoking this function) will normally be an inbound call, the other call will be an outbound call to an inbound service. The other call may already be connected, or it may still need to be placed.

Required argument:
  • other_call

    a reference to the outbound channel.

Optional arguments:
  • call_to

    the name of the inbound service, as entered on cloud.aculab.com. Default is None.

  • call_from

    the origin of the outbound call. Default is ‘’.

  • seconds_timeout

    time allocated to make the outbound call. Default is 120.

This is the high level function that will invoke a full-duplex connection between the lines owned by two active calls.

The other_call can be an IDLE channel. If it is, this function will place an outbound call on the channel using the call_to and call_from parameters. If the other_call has already been placed and is in CALL_OUTGOING state or further, then call_from and call_to do not have to be provided.

The current call does not have to be in ANSWERED state when this function is called, but it does have to be progressing.

If the current call isn’t ANSWERED, this function will place ringing on the current call (if it is an inbound call) when the other_call is in RING_OUTGOING state; and it will answer the current call once the other_call is in ANSWERED state.

If the current call is in ANSWERED state when the other_call is in RING_OUTGOING state; this function will use the tone player to play ringing to the current call.

Once both calls are in ANSWERED state the lines will be connected.

If seconds_timeout is not None, a timeout will apply for making and connecting the calls. The function will return False if the timeout is reached and the calls have not been connected. The default timeout is 120 seconds. A timeout will not affect the state of the calls.

If the current call state goes to IDLE this function will raise a Hangup exception and the other call will be hung up.

If the other call state goes to IDLE and the current call is not ANSWERED, the current call will be rejected with the cause provided by the other call, and the function will return False.

If the other call state goes to IDLE and the current call is ANSWERED, the function will return False without affecting the current call.

This function will block until the calls have been connected, the timeout has been reached, or either of the call states has returned to IDLE.

This function will return True on success, else False.

Usage example:

from prosody.uas.highlevel import HighLevelCallChannel

def main(channel, application_instance_id, file_man, my_log, application_parameters):
    out_channel = channel.ExtraChannel[0]

    high_level_channel = HighLevelCallChannel(channel, my_log)
    if high_level_channel.call_inbound_service_and_connect(out_channel, call_to='MyVoicemailRecorder',
                                                           call_from='bob@1234') is False:
        raise Hangup('Connect to inbound service failed')

    # the calls are connected, carry on
capture_input(prompt, speech_recognition_grammar, seconds_speech_recognition_timeout=10, digit_input_options=None, help_word=None, dtmf_help_digit='*', list_on_invalid_say=None, list_on_silence_say=None)

Use Text to Speech or play wav files to speak some options, get a speech or digit response.

Required arguments:
speech_recognition_grammar:

a object of type HighLevelGrammar object specifying the grammar to be used when performing speech recognition.

Optional arguments:
  • seconds_speech_recognition_timeout

    the amount of time to allow for speech recognition to complete. Default is 30 seconds.

  • digit_input_options

    a object of type HighLevelDigitInputOptions object. Setting this will allow DTMF digit input alongside speech. Default is None.

  • help_word

    a single word, not present in the grammar, that, when said, will cause prompt to be spoken again. Default is None.

  • dtmf_help_digit

    a digit that will cause prompt to be spoken again. Default is “*”.

  • list_on_invalid_say

    a list of PlayableMedia objects that will be spoken on incorrect DTMF responses. See below for default.

  • list_on_silence_say

    a list of PlayableMedia objects that will be spoken if no DTMF is detected. See below for default.

This is a high level function that helps to implement an Interactive voice response (IVR) system that uses Automatic Speech Recognition to recognise a voice response. It can also be used to respond to DTMF digit input.

This function will begin by speaking the prompt which is an object of type PlayableMedia, and which should contain a text string or audio file with all the required instructions - including the help option. For example, “Please enter your account number followed by the hash key; press star to hear the options again.” This should be played with barge-in enabled so that, at any point, the user can make a choice.

The help word

If a help word if specified, a pre-defined grammar cannot be used. If, for instance, the word “help” is specified, the speech grammar cannot be the pre-defined grammar “OneDigit”; a formatted grammar string will have to be supplied instead.

Speech recognition details

Speech recognition relies on a grammar that specifies the words or phrases that can be detected. Please have a look at the documentation at for details.

Speech recognition can begin as soon as the prompt begins to play, or as soon as it has finished playing. If the prompt has barge-in enabled, speech recognition will begin immediately - this will allow speech recognition to interrupt the prompt.

Please see the usage example below for details on creating a grammar object.

DTMF digit input details

By passing a HighLevelDigitInputOptions object to this function, DTMF digit detection is enabled which will allow the caller to press digits instead of speaking their response.

If dtmf_count is not set on the object, the user’s digits are collected until the dtmf_end_digit or dtmf_help_digit has been pressed. Note that the dtmf_help_digit must not be the same as the dtmf_end_digit. If dtmf_count is set, digits are collected until the correct number of digits has been reached, or dtmf_help_digit has been pressed.

If dtmf_count is set and the number of digits pressed is not correct, or if the dtmf_end_digit is required and it has not been detected before the timeout - but the user has pressed something - the first of the options supplied in list_on_invalid_say is spoken. If the user didn’t press any digits at all, the first of the options in list_on_silence_say is spoken. After speaking one of these, the function returns to the beginning. For each invalid choice, the next option in the list is spoken - and so on until the end of one of the lists is encountered, at which point the function will return.

The DTMF detector used for detecting the user options has a timeout (seconds_dtmf_timeout). If the timeout expires before any digits have been pressed, this counts as a silent choice. The same timeout applies between digit presses. If the timeout expires between digit entries, this counts as an invalid entry.

Once the digits have been collected, and the digit string does not contain the dtmf_help_digit, the function returns.

The default list_on_invalid_say has the following TTS strings “Sorry, I did not recognise that.”, “Please listen to the instructions, and then clearly say the relevant word or phrase.”

The default list_on_silence_say has the following TTS strings “Sorry, I did not recognise anything.”, “Please listen to the instructions, and then clearly say the relevant word or phrase.”

If the end of the list_on_invalid_say or list_on_silence_say list is seen, and no valid choice has been made, the function will return.

This function will return a CapturedInput object containing the words that were spoken, or the DTMF digits that were pressed, by the user; this will be None if the user fails to make a valid entry.

If the user hangs up, this function will raise a Hangup exception.

Usage example:

from prosody.uas import Hangup, Error, PlayableMedia
from prosody.uas.highlevel import HighLevelCallChannel, HighLevelGrammar, HighLevelDigitInputOptions

def main(channel, application_instance_id, file_man, my_log, application_parameters):

    high_level_channel = HighLevelCallChannel(channel, my_log)
    my_grammar = HighLevelGrammar('yes [please] | no [thanks];')
    my_digit_input_options = HighLevelDigitInputOptions(valid_digits='12', digit_count=1)

    # these two text strings are concatenated to become the prompt
    say_yesno  = "Would you like to order a pizza? "
    press_digit = "Please say yes or no. Or press 1 for yes or 2 for no."

    prompt = PlayableMedia(text_to_say=say_yesno + press_digit, channel=channel)

    response = high_level_channel.capture_input(prompt, speech_recognition_grammar=my_grammar,
                                                        digit_input_options=my_digit_input_options,
                                                        help_word='help')

    # if response is None, no valid input was detected
    if response is not None:
        # check whether we got speech or digits
        if response.type == response.Type.SPEECH:
            print("Caller said: {0}".format(response.input))
        else:
            print("Caller entered: {0}".format(response.input))
    else:
        print("Caller didn't respond")
    return 0
capture_number(prompt, dtmf_count=0, dtmf_end_digit='#', dtmf_help_digit='*', seconds_dtmf_timeout=5, list_on_invalid_say=None, list_on_silence_say=None)

Use Text to Speech or play wav files to speak some options, get a multiple digit DTMF response.

Required arguments:
  • prompt

    an object of type PlayableMedia that holds text to say using TTS, or the name of a file to play.

Optional arguments:
  • dtmf_count

    an integer representing the number of digits to collect. Default is 0 (no limit).

  • dtmf_end_digit

    a digit that will terminate the DTMF detector. Default is # (hash).

  • dtmf_help_digit

    a digit that will cause prompt to be spoken again. Default is * (star).

  • seconds_dtmf_timeout

    how long to wait for the user to press a digit before timing out.

  • list_on_invalid_say

    a list of PlayableMedia objects that will be spoken on incorrect DTMF responses. See below for default.

  • list_on_silence_say

    a list of PlayableMedia objects that will be spoken if no DTMF is detected. See below for default.

This is a high level function that helps to implement an Interactive voice response (IVR) system that can be used to collect a sequence of DTMF digits, for example, to collect a credit card number.

This function will begin by speaking prompt which is an object of type PlayableMedia, and which should contain a text string or a audio file that speaks all the required instructions, including the help option (for example, “please enter your account number followed by the hash key, press star to hear the options again.”). This should be played with barge in turned on, so at any point the user can make a choice.

If no options, except the prompt option, are given, DTMF collection will terminate on the dtmf_end_digit or the dtmf_help_digit being pressed. The default end digit is #, the default help digit is *.

If dtmf_count is not set, the user’s DTMF is collected until the dtmf_end_digit or dtmf_help_digit has been pressed. Note that the dtmf_help_digit must not be the same as the dtmf_end_digit. If dtmf_count is set, DTMF is collected until the correct number of digits has been reached, or dtmf_help_digit has been pressed.

If dtmf_count is set and the number of digits is not correct, or if the dtmf_end_digit is required and it has not been detected (but the user has pressed something), the first of the options supplied in list_on_invalid_say is spoken. If the user didn’t press any keys at all, the first of the options in list_on_silence_say is spoken. After speaking one of these, the function returns to the beginning. For each invalid choice, the next option in the list is spoken. And so on until the end of one of the lists is encountered; at which point the function will return.

The default list_on_invalid_say has the following TTS strings “Sorry, that was not a valid number.”, “Please listen to the instructions and enter a valid number.”

The default list_on_silence_say has the following TTS strings “Sorry, I did not hear that.”, “Please listen to the instructions and enter a valid number.”

If the end of the list_on_invalid_say or list_on_silence_say list is seen, and no valid choice has been made, the function will return.

The DTMF detector used for detecting the user options has a timeout (seconds_dtmf_timeout). If the timeout expires before any digits have been pressed, this counts as a silent choice. The same timeout applies between digit presses. If the timeout expires between digit entries, this counts as an invalid entry.

Once the digits have been collected, and the digit string does not contain the dtmf_help_digit, the function returns.

This function will return a string containing the DTMF digits chosen by the user. This will be None if the user fails to make a valid entry.

If the user hangs up, this function will raise a Hangup exception.

Usage example:

from prosody.uas import Hangup, Error, PlayableMedia
from prosody.uas.highlevel import HighLevelCallChannel

def main(channel, application_instance_id, file_man, my_log, application_parameters):

    high_level_channel = HighLevelCallChannel(channel, my_log)

    # these three text strings are concatenated to become the prompt
    say_hello  = "Please enter your fifteen digit account number, followed by the hash key. "
    say_option = "Or, if you have used this service before, enter only the last four digits, followed by the hash key. "
    say_help   = "If you make a mistake, you can return to the beginning by pressing star at any time."

    prompt = PlayableMedia(text_to_say=say_hello + say_option + say_help, channel=channel)

    digits = high_level_channel.capture_number(prompt)
    # if digits is None, no valid entry was detected
    if digits is not None:
        # check whether we got 15 or 4 digits
        if len(digits) == 15 or len(digits) == 4:
            # user has made a valid choice, do something and return
            return 0
    # user has made an invalid choice
    return -101
capture_validated_number(prompt, dtmf_valid_set=None, dtmf_count=0, dtmf_end_digit='#', dtmf_help_digit='*', seconds_dtmf_timeout=5, list_on_invalid_say=None, list_on_silence_say=None)

Use Text to Speech or play wav files to speak some options, get a multiple digit DTMF response.

Required arguments:
  • prompt

    an object of type PlayableMedia that holds text to say using TTS, or the name of a file to play.

Optional arguments:
  • dtmf_valid_set

    the string of digits that are allowed, pressing a digit that is not in this string is invalid.

  • dtmf_count

    an integer representing the number of digits to collect. Default is 0 (no limit).

  • dtmf_end_digit

    a digit that will terminate the DTMF detector. Default is # (hash).

  • dtmf_help_digit

    a digit that will cause prompt to be spoken again. Default is * (star).

  • seconds_dtmf_timeout

    how long to wait for the user to press a digit before timing out. Default is 5 seconds

  • list_on_invalid_say

    a list of PlayableMedia objects that will be spoken on incorrect DTMF responses. See below for default.

  • list_on_silence_say

    a list of PlayableMedia objects that will be spoken if no DTMF is detected. See below for default.

This is a high level function that helps to implement an Interactive voice response (IVR) system that can be used to collect a sequence of DTMF digits, for example, to collect a credit card number.

This function will begin by speaking prompt which is an object of type PlayableMedia, and which should contain a text string or a audio file that speaks all the required instructions, including the help option (for example, “please enter your account number followed by the hash key, press star to hear the options again.”). This should be played with barge in turned on, so at any point the user can make a choice.

If no options, except the prompt option, are given, DTMF collection will terminate on the dtmf_end_digit or the dtmf_help_digit being pressed. The default end digit is #, the default help digit is *.

If dtmf_count is not set, the user’s DTMF is collected until the dtmf_end_digit or dtmf_help_digit has been pressed. Note that the dtmf_help_digit must not be the same as the dtmf_end_digit. If dtmf_count is set, DTMF is collected until the correct number of digits has been reached, or dtmf_help_digit has been pressed.

If dtmf_count is set and the number of digits is not correct, or if the dtmf_end_digit is required and it has not been detected (but the user has pressed something), the first of the options supplied in list_on_invalid_say is spoken. If the user didn’t press any keys at all, the first of the options in list_on_silence_say is spoken. After speaking one of these, the function returns to the beginning. For each invalid choice, the next option in the list is spoken. And so on until the end of one of the lists is encountered; at which point the function will return.

The default list_on_invalid_say has the following TTS strings “Sorry, that was not a valid number.”, “Please listen to the instructions and enter a valid number.”

The default list_on_silence_say has the following TTS strings “Sorry, I did not hear that.”, “Please use your telephone keypad to enter a number.”

If the end of the list_on_invalid_say or list_on_silence_say list is seen, and no valid choice has been made, the function will return.

The DTMF detector used for detecting the user options has a timeout (seconds_dtmf_timeout). If the timeout expires before any digits have been pressed, this counts as a silent choice. The same timeout applies between digit presses. If the timeout expires between digit entries, this counts as an invalid entry.

Once the digits have been collected, and the digit string does not contain the dtmf_help_digit, the function returns.

This function will return a string containing the DTMF digits chosen by the user. This will be None if the user fails to make a valid entry.

If the user hangs up, this function will raise a Hangup exception.

Usage example:

from prosody.uas import Hangup, Error, PlayableMedia
from prosody.uas.highlevel import HighLevelCallChannel

def main(channel, application_instance_id, file_man, my_log, application_parameters):

    high_level_channel = HighLevelCallChannel(channel, my_log)

    # these three text strings are concatenated to become the prompt
    say_hello  = "Please enter your fifteen digit account number, followed by the hash key. "
    say_option = "Or, if you have used this service before, enter only the last four digits, followed by the hash key. "
    say_help   = "If you make a mistake, you can return to the beginning by pressing star at any time."

    prompt = PlayableMedia(text_to_say=say_hello + say_option + say_help, channel=channel)

    digits = high_level_channel.capture_validated_number(prompt)
    # if digits is None, no valid entry was detected
    if digits is not None:
        # check whether we got 15 or 4 digits
        if len(digits) == 15 or len(digits) == 4:
            # user has made a valid choice, do something and return
            return 0
    # user has made an invalid choice
    return -101
invoke_menu(menu, dtmf_valid_responses, dtmf_help_digit='*', seconds_dtmf_timeout=5, list_on_invalid_say=None, list_on_silence_say=None)

Use Text to Speech or play wav files to speak some options, collect a single digit DTMF response.

Required arguments:
  • menu

    an object of type PlayableMedia that holds text to say using TTS, or the name of a file to play.

  • dtmf_valid_responses

    a string containing the digits that are valid responses to the menu options. Digits allowed are 0123456789ABCD*#.

Optional arguments:
  • dtmf_help_digit

    a digit that will cause menu to be spoken again. Default is * (star).

  • seconds_dtmf_timeout

    how long to wait for the user to press a digit before timing out. Default is 5 seconds.

  • list_on_invalid_say

    a list of PlayableMedia objects will be spoken on incorrect DTMF responses. See below for default.

  • list_on_silence_say

    a list of PlayableMedia objects that will be spoken if no DTMF is detected. See below for default.

This is a high level function that helps to implement an Interactive voice response (IVR) system to drive a menu. DTMF collection is based on a single digit being pressed, and the digit that is pressed must be in the list supplied by dtmf_valid_responses.

This function will begin by speaking menu which is an object of type PlayableMedia, and which should contain a text string or a audio (wav) file that mentions all the valid DTMF responses, including the help option (for example, “Press 1 for this, press 2 for that, press star to hear the options again.”). This should be played with barge in turned on, so at any point the user can make a choice.

The user’s choice is collected. This choice can be the dtmf_help_digit, which will return the function to the beginning, or one of dtmf_valid_responses which will cause the function to return the digit selected. Note that the dtmf_help_digit must not also be in the list of dtmf_valid_responses.

If the choice is not one of the valid digits, or if the user doesn’t press a key, the first of the options supplied in list_on_invalid_say or list_on_silence_say is spoken. And then the function returns to the beginning. For each invalid choice, the next option in the list is spoken. And so on until the end of one of the lists is encountered; at which point the function will return.

The default list_on_invalid_say has the following TTS strings “Sorry, that was not a valid number.”, “Please enter a valid number using your telephone keypad.”

The default list_on_silence_say has the following TTS strings “Sorry, I did not hear that.”, “Please listen to the instructions and enter a valid number.”

If the end of the list_on_invalid_say or list_on_silence_say list is seen, and no valid choice has been made, the function will return.

The DTMF detector used for detecting the user options has a timeout (seconds_dtmf_timeout). If the timeout expires before any digits have been pressed, this counts as a silent choice.

This function will return a string containing the DTMF digit chosen by the user. This will be None if the user fails to make a valid choice.

If the user hangs up, this function will raise a Hangup exception.

Usage example:

from prosody.uas import Hangup, Error, PlayableMedia
from prosody.uas.highlevel import HighLevelCallChannel

def main(channel, application_instance_id, file_man, my_log, application_parameters):

    high_level_channel = HighLevelCallChannel(channel, my_log)

    # these three text strings are concatenated to become the menu
    say_hello   = "Hello, this is the BBC top stories reader. "
    say_options = "Press 1 for news. Press 2 for sport. Press 3 for entertainment. "
    say_help    = "Or press star to hear the options again."

    menu = PlayableMedia(text_to_say=say_hello + say_options + say_help, channel=channel)

    digit = high_level_channel.invoke_menu(menu, "123")
    # if digit is None, no valid entry was detected
    if digit is not None:
        # we got a 1, 2 or 3, do something ...
        return 0
    # user has made an invalid choice
    return -101