Voice dialer needed

Gert Doering (gert@greenie.muc.de)
Sat, 16 Jan 1999 17:25:09 +0100


Hi,

On Sat, Jan 16, 1999 at 04:20:18PM +0000, Antonio Fiol Bonnín wrote:
> I am starting a new service at the University, which has a very specific
> need.
> 
> When the server will need administrator action it will telephone the
> administrator to his mobile number and "tell" him what its
> problem/warning/work-request is.

You can do this with vm just fine.  I use it for a project at one of my
customers, to dial me if something is Really Hosed Up.

My script looks like this (needs a couple of .rmd files for the messages,
writes a status report to $3, telling the caller whether the person called
accepted (DTMF 1) or denied (DTMF 0) the job):

It's far from perfect, it's ugly, it's lacking serious error checking, but
it works.

gert

-------------- snap -------------
#!/usr/local/bin/vm shell

#
# This is a demo script for the new interface between shell scripts and
# the voice library (for dial-out)
#
# call as:
#     dialout PHONE VOICE-FILE.rmd STATUS.out
#

#
# Define the function to receive an answer from the voice library
#

function receive
     {
     read -r INPUT <&$VOICE_INPUT;
     echo "$INPUT";
     }

#
# Define the function to send a command to the voice library
#

function send
     {
     echo $1 >&$VOICE_OUTPUT;
     kill -PIPE $VOICE_PID
     }

#
# command line arguments
#

if [ $# -ne 3 ] ; then
    echo "Syntax: $0 <phone> <file.RMD> <statusfile>"
    exit 77
fi
phone="$1"
file="$2"
status="$3"

cd /usr/local/voice-call ||
    echo "CANNOT CHANGE TO VOICE DIRECTORY!!!" >&2

echo "Dialing $phone, then sending $file, status goes to $status..." >&2

#
# Let's see if the voice library is talking to us
#

ANSWER=`receive`

if [ "$ANSWER" != "HELLO SHELL" ]; then
     echo "$0: voice library not answering" >&2
     echo "ERROR" >$status
     exit 1
fi

#
# Let's answer the message
#

send "HELLO VOICE PROGRAM"

#
# Let's see if it worked
#

ANSWER=`receive`

if [ "$ANSWER" != "READY" ]; then
     echo "$0: initialization failed" >&2
     echo "ERROR" >$status
     exit 1
fi

#
# Set the device
#

send "DEVICE DIALUP_LINE"

#
# Let's see if it worked
#

ANSWER=`receive`

if [ "$ANSWER" != "READY" ]; then
     echo "$0: could not set output device" >&2
     echo "ERROR" >$status
     exit 1
fi

#
# Activate asynchronous events (DTMF tones, BUSY!)
#

send "ENABLE EVENTS"
ANSWER=`receive`

if [ "$ANSWER" != "READY" ] ; then
    echo "$0: could not enable events" >&2
    echo "ERROR" >$status
    exit 20
fi

#
# Now, dial out...
#

echo "All set up, dialing $phone..." >&2

send "DIAL $phone"

ANSWER="NOTREADY"
while [ ! -z "$ANSWER" -a "$ANSWER" != "READY" ] ; do
    ANSWER=`receive`

    echo "DIAL --> $ANSWER" 
done

if [ "$ANSWER" != "READY" ]; then
     echo "$0: could not start dial out (->error)" >&2
     echo "ERROR" >$status
     exit 1
fi

#
# Let's send $file $num times...
#

num=3
n_play=0;
DTMF=""
rc="ERROR"

while [ $n_play -lt $num -a -z "$DTMF" -a -n "$ANSWER" ] ; do

    send "PLAY $file"

    while [ -n "$ANSWER" ] ; do

	ANSWER=`receive`

	echo "Playing... got: $ANSWER" >&2

	case "$ANSWER" in
	    PLAYING) ;;			# ignore (it's an ACK)
	    READY) break ;;		# leave loop
	    BUSY_TONE) DTMF="b"; break ;;
	    RECEIVED_DTMF)
		DTMF=`receive`
		test "$DTMF" = "READY" && DTMF=`receive`
		echo "got DTMF tone: $DTMF" >&2
		break ;;
	    "") echo "ERROR" >$status ; exit 1 ;;
	    *) echo "unrecognized status: $ANSWER " >&2 ;;
	esac

    done

    n_play=`expr $n_play + 1`
done

#
# if it was a DTMF tone, stop playing now...
#
if [ -n "$DTMF" ] ; then
    send "STOP"

    ANSWER=`receive`
    if [ "$ANSWER" != "READY" ] ; then
	    echo "Can't stop playing (ready: $ANSWER)!" >&2
	    rc="ERROR - [stop play]"
    fi

    if [ "$DTMF" = "b" ] ; then
	rc="NAK -- BUSY"
    else
	# and acknowledge!
	send "BEEP"

	ANSWER="nothing"
	while [ "$ANSWER" != "READY" -a -n "$ANSWER" ]
        do
	    ANSWER=`receive`
	    echo "BEEP --> $ANSWER..." >&2
	done

	# send acknowledge message
	case $DTMF in
	    1|2|3|4|5|6|7|8)	
		    rc="OK -- HIS JOB"; 
		    job="auftrag-angenommen.rmd";;
	    9)
		    rc="NEVER -- NEVER AGAIN!"; 
		    job="auftrag-abgelehnt.rmd";;
	    *)
		    rc="NAK -- PRESSED 0";
		    job="auftrag-abgelehnt.rmd";;
	esac

	echo "PLAYING ACKNOWLEDGE: $job" >&2
	send "PLAY $job"

	ANSWER=`receive`
	if [ "$ANSWER" != "PLAYING" ] ; then
	    echo "$job: unknown answer (playing: $ANSWER)" >&2
	else
	    ANSWER=`receive`
	    if [ "$ANSWER" != "READY" ] ; then
		echo "$job: unknown answer (ready: $ANSWER)" >&2
	    fi
	fi

    fi
else		# no DTMF tone
    test $n_play -eq $num && \
		rc="NAK -- NO TONE PRESSED"
fi


#
# Let's say goodbye
#

send "GOODBYE"

#
# Let's see if the voice library got it
#

ANSWER=`receive`

if [ "$ANSWER" != "GOODBYE SHELL" ]; then
     echo "$0: could not say goodbye to the voice library ($ANSWER)" >&2
fi

echo "Goodbye... exit code is: $rc"

echo "$rc" >$status

exit 0

-------------- snap -------------
-- 
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             gert@greenie.muc.de
fax: +49-89-35655025                        gert.doering@physik.tu-muenchen.de