The #OpenSourceLounge

(Lorne Gaetz) #83

Next open source lounge is a week from tonight:

(Lorne Gaetz) #84

:arrow_up: :arrow_up: :arrow_up: Reminder of tonights Open Source Lounge at 7pm Eastern :arrow_up: :arrow_up: :arrow_up:

(Lorne Gaetz) #85

Good session tonight. @slobera did a pretty detailed walkthru on how to use Dynamic Routes for phone surveys and for reporting on IVR selections and @dicko talked about using vosk for speech to text.

Thanks guys.


To reduce it to the basics , vosk is a very lightweight offline STT parser that uses the kaldi speech engine and can easily run in a docker container on a Pi4 or bigger. So after doing the

thing, you can construct a dialplan stub much like

exten = 999,1,Answer
same = n,Wait(1)
; a red herring here same = n,Monitor(wav,dick-${STRFTIME(${EPOCH},,%Y%m%d_%H%M%S)})
same = n,SpeechCreate
same = n,SpeechBackground(pls-entr-num-uwish2-call)
same = n,StopMonitor
same = n,noop(${SPEECH_TEXT(0)})
same = n,Set(result=${SHELL(/var/lib/asterisk/bin/ "${SPEECH_TEXT(0)}")})
same = n,Playback(you-entered)
same = n,SayDigits(${result})

same = n,noop(${result})

where is much like

import sys
import phonenumbers
# dicktionary (sic) of acceptable words
num_dict = {
# button name pronounced or mis-pronounced
    'oh' : '0',
    'no' : '0',
    'o' : '0',
    'zero' : '0',
    'reject' : '0',
    'one': '1',
    'accept' : '1',
    'yes' : '1',
    'won': '1',
    'two': '2',
    'to': '2',
    'too': '2',
    'three': '3',
    'four': '4',
    'for': '4',
    'fool': '4',
    'five': '5',
    'six': '6',
    'seven': '7',
    'eight': '8',
    'nine': '9',
    'plus' : '+',
    'pound' : '#',
    'hash' : '#',
    'star' : '*',
    'asterisk' : '*',
    'hundred' : '00',
# nusance words to be ignored here
    'call' : '',
    'please' : '',
    'dial' : '',
# IVR or other endpoints described here
    'sales' : '602',
    'accounts' : '*666',
    'accounting' : '*666',
    'operator' : '0',
# speed dials can be constructed here
    'dick'   : '13235551212',
    'tom'   : '12125551212',

phone_number = sys.argv[1]
outnum = ""
for word in phone_number.split():
        outnum  += (num_dict[word])
if outnum == "":
    print ("nothing heard\n", file=sys.stderr)
    print ("noaudio")
if outnum == "911":
    print ("emergency routines need to be put here !!!!!!!")
print ("I heard",outnum,file=sys.stderr)
if len(outnum)> 9:
    parsednum = phonenumbers.parse(outnum, "US")
    valid= phonenumbers.is_valid_number(parsednum)
    if valid:
        willdial = phonenumbers.format_number(parsednum, phonenumbers.PhoneNumberFormat.E164)
        dialnum = phonenumbers.parse(willdial, None)
        print ("Validated as", dialnum, "\n", file=sys.stderr)
        print (willdial, end='')
        if not valid:
            woulddial = phonenumbers.format_number(parsednum, phonenumbers.PhoneNumberFormat.E164)
            print ("Would try and dial  ", woulddial, "but that is an invalid number\n" , file=sys.stderr)
            print (outnum,"\b,invalid", end='')
    print ("Will dial",outnum, "\n", file=sys.stderr)
    print (outnum, end = '')

The python script is also intended to be useful as a speech to text dialer plus number verifier and ‘normalizer’ that will recognize most every e164 ‘text’ strings

“plus three three . . .” will check France
“oh oh three three . . .” also.
Whereas “one one three three for oh oh won one one too” will be rejected as an invalid NANP number.
But “two oh one for four four one two three four” is seen as legit.

All valid numbers longer than nine digits after parsing recognized words are returned in e164 nomenclature if valid.

Those less are returned ‘as said’ within the limitations of the ‘dicktionary’ which enables access to all dialplans internal to FreePBX, thereby bypassing any DTMF detection, (great for anti-spam IMHO )

Food for thought here?


Perhaps a moderator could appropriately split this off to a new thread, it really should not be here in this #OpenSourceLounge thread, (Mea Culpa :slight_smile: )

(Tom Ray) #87

Just FYI, by Asterisk 21 (so two years) things like Monitor, Macro, MeetMe and Chan_SIP are marked for removal. I would highly suggest looking at updating any custom scripts or dialplan dependant on them with their proper replacements.


There is currently no “proper” replacement for monitor in this app, which is why I use it here.

I only want the ‘in’ leg, the out leg that mixmonitor always mixes down to mono would pollute my later ‘vectorizing’ of the speaker.