IVR Menu to capture double digit

Hi all am implementing IVR menu using stream file like this

`

$result = $agi->stream_file(“/var/lib/asterisk/agi-bin/files/soundFile”, ‘1234567890#*’);

`

The IVR menu has 10 options and I have problem capturing option 10, because the ascii code is only between 0 to 9. Any idea how to capture double digit like 10 or 12 or 14?

How do you plan on differentiating between 1 an 11?

Are you going to always ask the caller to enter 2 digits?

@sedwards The IVR menu structure is like: press 1 for English, press 2 for French,… press 10 for German, press 11 for Spanish

I will disclose that I have not done much with AGI.

Stream_File only supports a single digit. As soon as one of the “escape” digits is pressed (which is what you specify); the application immediately exits with the return code of whatever was pressed.

There are two ways I can think of to handle this. The first would be use wait_for_digit after stream_file escapes to handle a second digit press. Give the user a few ms to enter the next digit. You would then have to have your script handle it further.

The next would be to do something other than stream_file to play your menu options while waiting for user input. In dialplan world we do this with Background.

Is there a specific reason you have to use AGI? I get how cool it is; but for an IVR like this with multiple digits; dialplan makes it a lot easier. You could even use normal dialplan for the user input and then call your AGI script.

@dewdude thanks for for your input.
Wait for degit did not work, stream file still capture the first digit pressed.
I used read app in the dialplan to capture multiple digits so will try it or the Background App you suggested.

Am actually using PHPAGI to have more control with handle some logic with php and also have more control with the MySQL database query.

Background and WaitExten are applications that need to be run directly as part of a dialplan, not as subordinate to the AGI application. They don’t actually read the digits themselves but set the dialplan interpreter into a state in which it trying to read an extension number, itself.

While they are a better way of doing an IVR, that IVR needs to be implemented as dialplan, not as AGI.

You can ‘capture [a] double digit’ entry in an AGI. The basic flow is to stream a file. The first key stroke stops the playback. You wait for the second key stroke. You multiply the first by 10 and add the second. Write the value to a channel variable and do something with it in your dialplan. Bob’s your uncle.

Depending on what you are trying to accomplish, handling it in dialplan can be done with something like:

; please enter your credit card valid expiration date                                                                                                                        
[enter-expiration-date](h,i,s,max-timeout,digit-timeout)                                                                                                                     
        exten = s,1,                    verbose(1,[${EXTEN}@${CONTEXT}])
        exten = s,n,                    background(please-enter-expiration-date)                                                                                                          
        exten = _xxxx,1,                set(EXPIRATION-DATE=${EXTEN})                                                                                                        
        exten = _xxxx,n,                agi(check-expiration-date)                                                                                                           
        exten = _xxxx,n(invalid-date),  set(DATE-TRY-COUNTER=$[${DATE-TRY-COUNTER} - 1])                                                                                     
        exten = _xxxx,n,                gotoif($[${DATE-TRY-COUNTER} < 0]?enter-card-number,s,1)                                                                             
        exten = _xxxx,n,                background(invalid-expiration-date)                                                                                                          
        exten = _xxxx,n,                goto(enter-expiration-date,s,1)                                                                                                      
        exten = _xxxx,n(valid-date),    goto(auth-card,s,1)                                                                                                                  

Note that this snippet is from a very old (2004?) dialplan, so YMMV.

Based on my understanding an AGI script just “takes control” of Asterisk the same way a dialplan would. You can call the same applications you would from dialplan using EXEC.

print "EXEC Background \"$filterList[$n][2]&$FESTIVALCACHE/jukebox_$filterList[$n][0]\"\n";
			my $result = <STDIN>;
			$digit = &check_result($result);
			if ($digit > 0) {
				$digitstr .= chr($digit);
				last;

This snippit from an AGI script, I believe; will take in multiple digits; though I’m not 100% sure how. It’s executing Background though.

But, I believe, in theory; it’s possible to literally just pass control to an AGI script and it then just calls existing dialplan applications.

I think you need to determine which logic you can handle in PHPAGI, and which needs to be dialplan. I’m pretty sure what you want to do can be done in pure AGI; but some of it’s going to be easier in dialplan. But if you’re doing it in pure AGI; then you likely need to constantly have it listening for digits in cases where multiples exist.

I don’t know what logic you can do with PHPAGI that you can’t do in Dialplan exactly.

Background only reads one digit. There is an optional setting (see below - it is not explicitly exposed) as to what it does if one digit would be enough. Either it will simulate a GoTo to that extension, and return success, with no digit, or it will return a special non-zero code which is that actual digit, in which case, if called directly from the dialplan, will result in the dialplan effectively restarting in a mode where it is reading an extension number itself. If more than one digit is possible, it will always return the first digit as a return code.

It looks like the AGI EXEC command forces it into the mode in which it always returns the digit, rather than allowing it to do a GoTo for single digit extensions. Some of the comments remark on its use by AGI scripts as being “unconventional”.

If you do exec it from AGI, you will still need to read any second digit separately

If you’re going to do this in an AGI, i suspect you will have better success using AGI ‘correctly’ – skip ‘exec background’ kludge and use ‘stream file’ for the first digit and ‘wait for digit’ for the second.

Also, you should use an established AGI library. It is better for so many reasons than cobbling something together piecemeal.

This is the method I use.

Like I said…all my experience has been in dialplan. I made an incorrect assumption the dialplan applications worked the same when accessed from AGI. I would have figured this out when I sat down and tried to do something in AGI. It made sense after reading some stuff before falling alseep last night.

The idea of using stream file to capture first digit then use wait for digit for additional was my first instinct.

I think OP has the pieces…just needs to figure out how to assemble them.