| 
									
										
										
										
											2005-08-10 23:24:39 +00:00
										 |  |  | Asterisk External IVR Interface | 
					
						
							|  |  |  | ------------------------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If you load app_externalivr.so in your Asterisk instance, you will | 
					
						
							|  |  |  | have an ExternalIVR() application available in your dialplan. This | 
					
						
							|  |  |  | application implements a simple protocol for bidirectional | 
					
						
							|  |  |  | communication with an external process, while simultaneous playing | 
					
						
							|  |  |  | audio files to the connected channel (without interruption or | 
					
						
							|  |  |  | blocking). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  | There are two ways to use ExternalIVR(); you can execute an | 
					
						
							|  |  |  | application on the local system or you can establish a socket | 
					
						
							|  |  |  | connection to a TCP/IP socket server. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To execute a local application use the form: | 
					
						
							|  |  |  | ExternalIVR(/full/path/to/applcation[(arguments)],options) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The arguments are optional, however if they exist they must be | 
					
						
							|  |  |  | enclosed in parentheses. The external application will be executed | 
					
						
							|  |  |  | in a child process, with its standard file handles connected to the | 
					
						
							|  |  |  | Asterisk process as follows: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | stdin (0)  - events will be received on this handle | 
					
						
							|  |  |  | stdout (1) - commands can be sent on this handle | 
					
						
							|  |  |  | stderr (2) - messages can be sent on this handle | 
					
						
							|  |  |  | * Use of stderr for message communication is discouraged because | 
					
						
							|  |  |  | it is not supported by a socket connection. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To create a socket connection use the form: | 
					
						
							|  |  |  | ExternalIVR(ivr://host[:port][(arguments)],options) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The host can be a fqdn or an ip address. The port is optional, if | 
					
						
							|  |  |  | not specified the default of 2949 will be used. The arguments are | 
					
						
							|  |  |  | optional however if they exist they must be enclosed in parentheses. | 
					
						
							|  |  |  | TheExternalIVR application will connect to the specified socket | 
					
						
							|  |  |  | server and establish a bi-directional socket connection, where | 
					
						
							|  |  |  | events will be sent to the TCP/IP server and commands received | 
					
						
							|  |  |  | from it. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The specific ExternalIVR options, events and commands are detailed | 
					
						
							|  |  |  | below. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Upon execution, if not specifically prevented by an option, the | 
					
						
							|  |  |  | ExternalIVR application will answer the channel (if it's not | 
					
						
							|  |  |  | already answered), create an audio generator, and start playing | 
					
						
							|  |  |  | silence. When your application wants to send audio to the channel, | 
					
						
							|  |  |  | it can send a command (see below) to add a file to the generator's | 
					
						
							|  |  |  | playlist. The generator will then work its way through the list, | 
					
						
							|  |  |  | playing each file in turn until it either runs out of files to | 
					
						
							|  |  |  | play, the channel is hung up, or a command is received to clear | 
					
						
							|  |  |  | the list and start with a new file. At any time, more files can | 
					
						
							|  |  |  | be added to the list and the generator will play them in sequence. | 
					
						
							| 
									
										
										
										
											2005-08-10 23:24:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | While the generator is playing audio (or silence), any DTMF events | 
					
						
							|  |  |  | received on the channel will be sent to the child process (see | 
					
						
							|  |  |  | below). Note that this can happen at any time, since the generator, | 
					
						
							|  |  |  | the child process and the channel thread are all executing | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  | independently. It is very important that your external application | 
					
						
							|  |  |  | be ready to receive events from Asterisk at all times (without | 
					
						
							|  |  |  | blocking), or you could cause the channel to become non-responsive. | 
					
						
							| 
									
										
										
										
											2005-08-10 23:24:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  | If the child process dies, or the remote server disconnects, | 
					
						
							|  |  |  | ExternalIVR() will notice this and hang up the channel | 
					
						
							|  |  |  | immediately (and also send a message to the log). | 
					
						
							| 
									
										
										
										
											2005-08-10 23:24:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-22 05:10:01 +00:00
										 |  |  | ExternalIVR() Options | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  | --------------------- | 
					
						
							| 
									
										
										
										
											2008-05-22 05:10:01 +00:00
										 |  |  | n: 'n'oanswer, don't answer an otherwise unanswered channel. | 
					
						
							|  |  |  | i: 'i'gnore_hangup, instead of sending an 'H' event and exiting | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  |    ExternalIVR() upon channel hangup, it instead sends an 'I' | 
					
						
							|  |  |  |    event and expects the external application to exit the process. | 
					
						
							| 
									
										
										
										
											2008-05-22 05:10:01 +00:00
										 |  |  | d: 'd'ead, allows the operation of ExternalIVR() on channels that | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  |    have already been hung up. | 
					
						
							| 
									
										
										
										
											2008-05-22 05:10:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  | Events | 
					
						
							|  |  |  | ------ | 
					
						
							| 
									
										
										
										
											2005-08-10 23:24:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  | All events are be newline-terminated strings and are sent in the | 
					
						
							|  |  |  | following format: | 
					
						
							| 
									
										
										
										
											2005-08-10 23:24:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-24 14:24:55 +00:00
										 |  |  | tag,timestamp[,data] | 
					
						
							| 
									
										
										
										
											2005-08-10 23:24:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The tag can be one of the following characters: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 0-9: DTMF event for keys 0 through 9 | 
					
						
							|  |  |  | A-D: DTMF event for keys A through D | 
					
						
							|  |  |  | *: DTMF event for key * | 
					
						
							|  |  |  | #: DTMF event for key # | 
					
						
							|  |  |  | H: the channel was hung up by the connected party | 
					
						
							| 
									
										
										
										
											2007-01-23 04:45:43 +00:00
										 |  |  | E: the script requested an exit | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  | Z: the previous command was unable to be executed. There may be a | 
					
						
							|  |  |  |    data element if appropriate, see specific commands below for | 
					
						
							|  |  |  |    details | 
					
						
							| 
									
										
										
										
											2009-11-10 17:33:47 +00:00
										 |  |  | T: the play list was interrupted (see S command below) | 
					
						
							| 
									
										
										
										
											2005-08-24 14:24:55 +00:00
										 |  |  | D: a file was dropped from the play list due to interruption (the | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  |    data element will be the dropped file name) NOTE: this tag | 
					
						
							|  |  |  |    conflicts with the D DTMF event tag. The existence of the data | 
					
						
							|  |  |  |    element is used to differentiate between the two cases | 
					
						
							| 
									
										
										
										
											2005-08-24 14:24:55 +00:00
										 |  |  | F: a file has finished playing (the data element will be the file | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  |    name) | 
					
						
							| 
									
										
										
										
											2008-05-22 05:10:01 +00:00
										 |  |  | P: a response to the 'P' command (see below) | 
					
						
							|  |  |  | G: a response to the 'G' command (see below) | 
					
						
							|  |  |  | I: a Inform message, meant to "inform" the client that something | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  |    has occurred.  (see Inform Messages below) | 
					
						
							| 
									
										
										
										
											2005-08-10 23:24:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The timestamp will be 10 digits long, and will be a decimal | 
					
						
							|  |  |  | representation of a standard Unix epoch-based timestamp. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Commands | 
					
						
							|  |  |  | -------- | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  | All commands are newline-terminated strings. | 
					
						
							| 
									
										
										
										
											2005-08-10 23:24:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  | The child process can send one of the following commands: | 
					
						
							| 
									
										
										
										
											2005-08-10 23:24:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | S,filename | 
					
						
							|  |  |  | A,filename | 
					
						
							|  |  |  | H,message | 
					
						
							| 
									
										
										
										
											2007-01-23 04:45:43 +00:00
										 |  |  | E,message | 
					
						
							| 
									
										
										
										
											2010-09-10 13:13:16 +00:00
										 |  |  | D,dtmf[,interval][,duration] | 
					
						
							| 
									
										
										
										
											2005-08-24 14:24:55 +00:00
										 |  |  | O,option | 
					
						
							| 
									
										
										
										
											2008-05-22 05:10:01 +00:00
										 |  |  | V,name=value[,name=value[,name=value]] | 
					
						
							|  |  |  | G,name[,name[,name]] | 
					
						
							|  |  |  | L,log_message | 
					
						
							|  |  |  | P,TIMESTAMP | 
					
						
							|  |  |  | T,TIMESTAMP | 
					
						
							| 
									
										
										
										
											2005-08-10 23:24:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The 'S' command checks to see if there is a playable audio file with | 
					
						
							|  |  |  | the specified name, and if so, clear's the generator's playlist and | 
					
						
							|  |  |  | places the file onto the list. Note that the playability check does | 
					
						
							|  |  |  | not take into account transcoding requirements, so it is possible for | 
					
						
							| 
									
										
										
										
											2009-11-20 17:28:01 +00:00
										 |  |  | the file to not be played even though it was found. If the file does | 
					
						
							|  |  |  | not exist it sends a Z response with the data element set to the file | 
					
						
							|  |  |  | requested. If the generator is not currently playing silence, then T | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  | and D events will be sent to signal the playlist interruption and | 
					
						
							|  |  |  | notify it of the files that will not be played. | 
					
						
							| 
									
										
										
										
											2005-08-10 23:24:39 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The 'A' command checks to see if there is a playable audio file with | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  | the specified name, and if so, appends it to the generator's playlist. | 
					
						
							|  |  |  | The same playability and exception rules apply as for the 'S' command. | 
					
						
							| 
									
										
										
										
											2005-08-10 23:24:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-10 13:13:16 +00:00
										 |  |  | The 'H' command logs the supplied message to the Asterisk log, stops | 
					
						
							|  |  |  | the generator, hangs up the channel and terminates the ExternalIVR | 
					
						
							|  |  |  | application. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  | The 'E' command logs the supplied message to the Asterisk log, stops | 
					
						
							|  |  |  | the generator and terminates the ExternalIVR application, but continues | 
					
						
							|  |  |  | execution in the dialplan. | 
					
						
							| 
									
										
										
										
											2007-01-23 04:45:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-10 13:13:16 +00:00
										 |  |  | The 'D' command generates DTMF on the channel, dtmf is a string of one or | 
					
						
							|  |  |  | more valid DTMF digits, w can be used for a half second pause. Interval | 
					
						
							|  |  |  | is optional, defaults to 250 milliseconds and is the time between digits. | 
					
						
							|  |  |  | Duration is optional and is the duration of each digit. | 
					
						
							| 
									
										
										
										
											2005-08-10 23:24:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-24 14:24:55 +00:00
										 |  |  | The 'O' command allows the child to set/clear options in the | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  | ExternalIVR() application. | 
					
						
							| 
									
										
										
										
											2005-08-24 14:24:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  | The supported options are: | 
					
						
							|  |  |  | (no)autoclear: Automatically interrupt and clear the playlist | 
					
						
							|  |  |  |                upon reception of DTMF input. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The 'T' command will answer an unanswered channel. If it fails either | 
					
						
							| 
									
										
										
										
											2008-05-22 05:10:01 +00:00
										 |  |  | answering the channel or starting the generator it sends a Z response | 
					
						
							|  |  |  | of "Z,TIMESTAMP,ANSWER_FAILED" or "Z,TIMESTAMP,GENERATOR_FAILED" | 
					
						
							|  |  |  | respectively. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The 'V' command sets the specified channel variable(s) to the specified | 
					
						
							|  |  |  | value(s). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The 'G' command gets the specified channel variable(s).  Multiple | 
					
						
							|  |  |  | variables are separated by commas.  Response is in name=value format. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The 'P' command gets the parameters passed into ExternalIVR() minus | 
					
						
							|  |  |  | the options to ExternalIVR() itself: | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  |         If ExternalIVR() is executed as: | 
					
						
							|  |  |  |                 ExternalIVR(/usr/bin/foo(arg1,arg2),n) | 
					
						
							|  |  |  |         The response to the 'P' command would be: | 
					
						
							|  |  |  |                 P,TIMESTAMP,/usr/bin/foo,arg1,arg2 | 
					
						
							| 
									
										
										
										
											2010-09-10 13:13:16 +00:00
										 |  |  | NOTE: This is the only way for a TCP/IP server to be able to retrieve | 
					
						
							| 
									
										
										
										
											2010-01-18 17:51:09 +00:00
										 |  |  | the arguments. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The 'L' command puts a message into the Asterisk log. NOTE: This is | 
					
						
							|  |  |  | prefered to using stderr and is the only way for a TCP/IP server to | 
					
						
							|  |  |  | log a message. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Inform Messages | 
					
						
							|  |  |  | --------------- | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The only inform message that currently exists is a HANGUP message, | 
					
						
							|  |  |  | in the form I,TIMESTAMP,HANGUP and is used to inform of a hangup | 
					
						
							|  |  |  | when the i option is specified. | 
					
						
							| 
									
										
										
										
											2007-01-23 04:45:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-10 23:24:39 +00:00
										 |  |  | Errors | 
					
						
							|  |  |  | ------ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Any newline-terminated output generated by the child process on its | 
					
						
							|  |  |  | stderr handle will be copied into the Asterisk log. |