Making your ivr nodes (call) flow with PAGI

Link the PHP nodes of your Telephony Application or IVR for Asterisk PBX

"Advanced telephony applications with PHP and PAGI using call flow nodes" was about how to create call flow nodes for asterisk, using pagi and php, to easily create telephony applications. It's now time to add a layer on top of it, and create a complete call flow with several nodes.

First, a couple of useful links:

So what is a NodeController and how it can be used from PHP for your Asterisk PBX Application?

A NodeController is what controls the execution flow of the nodes in your ivr application. You can register nodes in a node controller, and also register actions, to be executed based on their specific result when they are done executing.

For example, you could register a jump to another node when the user inputs some specific digits, or when he/she has reached the maximum input attempts to enter a valid option in a menu, or when the node has been cancelled by pressing the cancel digit, etc.

This is effectively a complete Call Flow, composed by different nodes and some specific behavior to control how the user navigates through them.

Why should I use nodes in my VoIP Application?

It's not like you wont be able to do your application without them. Their main purpose is to save yourself from coding if's and switch-case's to make decisions in your code after executing every node. So instead of coding these, you will just write declarative code that defines how a node controller will control and execute these nodes.

Below is a brief description of the available results and actions that a NodeController can evalute and carry on when dealing with the Nodes execution.

List of available Results of your IVR nodes

  • onCancel(): Execute an action when the node is cancelled with the cancel digit.
  • onComplete(): Execute an action when the node is completed successfully (not a cancelled node, and not an exceeded input attempts). Often used in conjunction with withInput().
  • onMaxAttemptsReached(): Execute an action when the node ended with maximum attempts exceeded for a valid input.
  • withInput($input): Will check that the user has entered $input before executing the action.

List of available Actions for an IVR node

  • hangup($cause): Hangup the communication with the given cause code.
  • jumpTo($nodeName): Jump to the given node (by name).
  • jumpAfterEval(Closure $callback): Evaluates the given callback. This callback must accept the currently running node, and return a string which is the name of the next node to jump to.
  • execute(Closure $callback): Execute a callback.

Creating a NodeController to put it all together and create a full VoIP Application

Creating a node controller is as easy as this. First, get a pagi client instance, as usual:

Then, instantiate a NodeController:

Registering a Node in the NodeController

Nodes can be registered through the register() method, which returns a Node, creating a fluent interface for it:

Executing the node controller

Once you registered your nodes, you can execute them by jump()ing to them:

Typically you would only do this when starting your application. At this stage, you are jumping to the first node, and then the NodeController will figure how to execute the other nodes by itself. See below.

Spicing it a little bit with Results and Actions

We havent done anything useful yet. We only have 1 node and we are executing it programatically. Let's add a node that will play a sound file to the user when it has reached the maximum input attempts for the above main menu:

And let's now register a result handler for this node, that will hangup the communication after playing the sound file:

So far we have added a new node that will just play a sound file. When the node completes, the NodeController will execute the action configured, in this case a hangup with the cause code 16.

Let's now configure a result handler for the main menu, that will jump to the "maxAttemptsReached" node when the user has exceeded the maximum input attempts to enter a valid option:

Completing the menu with conditional jumps in PHP

Let's add some behavior to the main menu so it will jump to other nodes based on the option chosen by the user:

Let's now add the help node, that when completed or cancelled will go back to the main menu:

Coding complex application logic in PHP

Sometimes you need to take decisions based on some more complex logic, for example if the user has input a calling card pin, you will sure need to validate it or try to get that entity from the database, and jump to one node or another based on these things. For this particular case, you can use the action jumpAfterEval(), like so:

Note that the Nodes have validators, that will usually suffice to do whatever needed before marking a node as complete. The code above is just an example, and a better implementation would be to use a node validator.

Start writing full PHP Telephony Applications for the Asterisk PBX

Using a NodeController clearly allows you to code less if's and switch-cases's and concentrate on the really important stuff of you ivr application. It might not be a killer feature, and maybe the nodes themselves are more important than the node controllers, but they are very useful once you get used to work with them. Creating a complete callflow in php for asterisk should be a lot more fun now :)