Voice Blog using Asterisk AGI

Isn’t it nice to have your own voice blogging solution where you can share your voice blogs, discuss with in your friends or private groups. Asterisk, the most used open source IP PBX is there to create your own voice blogging platform.

In this document, I described, how to create a voice blogging platform using asterisk’s dial plan with AGI functions.


  • Record and listen your own voice
  • Search and listen your friend’s voice using his/her cell no.

Component used

  • Asterisk 3.0.1 with FreePBX
  • Asterisk Gateway Interface (AGI)
  • PHP
  • MySQL

How it works

Like any other IVR application, this application also designed with menu based choice selection. Dial plan has been used to handle the choice tree, voice record and play. vBlog associated information has been stored in MySQL table and AGI has been used to access that information through PHP.


  1. Make sure your installed distribution contains AGI with phpagi class
localhost*CLI> module show like agi
Module                         Description                           Use Count
res_agi.so                     Asterisk Gateway Interface (AGI)         1
1 modules loaded

2. Check the phpagi.php file in your asterisk installation path/agi-bin directory. In my case it is in /var/lib/asterisk/agi-bin

[root@localhost agi-bin]# pwd
[root@localhost agi-bin]# ls ph*
phpagi-asmanager.php phpagi.php

3. Check MySQL configuration

[root@localhost ~]# service mysqld status
mysqld (pid 1357) is running…

4. Configure cdr_msql.conf for storing CDR
[root@localhost asterisk]# pwd
[root@localhost asterisk]# more cdr_mysql.conf

hostname = <your DB hostname>
dbname=<your DB name>
password = <your password>
user = <your username>

5. Create a table in your database to store vblog information. In my case, I used following table structure

CREATE TABLE `voice_rec` (
  `rec_id` mediumint(9) NOT NULL AUTO_INCREMENT,
  `caller_id` varchar(11) NOT NULL,
  `rec_date` datetime DEFAULT NULL,
  `approved` bit(1) DEFAULT NULL,
  `rec_file_name` varchar(20) NOT NULL,
  `c_like` int(11) DEFAULT NULL,
  PRIMARY KEY (`rec_id`)

Now we are ready to design the application. So for this example we need a main menu and two legs with following distribution


main menu – Welcome prompt and prompts for each leg e.g. a) press one to record your voice b) press two to search and listen your friends voice

Next step is to configure dial plan. Here is how it looks like.

exten => 100,1,Answer()
exten => 100,n,Playback(custom/welcome) ;Welcome prompt
exten => 100,n,Goto(mainmenu,s,1)
;Main menu
exten => s,1,Answer()
exten => s,n,Set(br=${br}0-) ;variable to record caller’s navigation
exten => s,n(lbl_mainmenu_0),Set(TIMEOUT(response)=5)
exten => s,n,Set(TIMEOUT(digit)=1)
exten => s,n,Background(custom/main_menu) ;Menu choice prompt 
exten => s,n,WaitExten()
exten => I,1,Playback(custom/invalid)
exten => i,n,Goto(s,lbl_mainmenu_0)
exten => t,1,Goto(s,lbl_mainmenu_0)
exten => h,1,Set(CDR(userfield)=${br})
exten => 1,1,Goto(menu-1,s,1)
exten => 2,1,Goto(menu-2,s,1)
exten => 3,1,Goto(menu-3,s,1)
exten => s,1,Playback(custom/B1L1) ;prompt “Record your voice after beep”
exten => s,n,Set(fname=${STRFTIME(${EPOCH},,%Y%m%d)}-${CALLERID(num)})
exten => s,n,Set(clid=${CALLERID(num)})
exten => s,n,Set(rdate=${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M:%S)})
exten => s,n,Set(br=${br}1-)
exten => s,n,Playback(beep)
exten => s,n,Record(custom/customer/${fname}.wav)
exten => s,n,Set(TIMEOUT(response)=5)
exten => s,n,Set(TIMEOUT(digit)=1)
exten => s,n,Background(custom/B1L2) ;prompt to get confirmation to save (1 to save, 2 to discard) the blog after playback
exten => s,n,Playback(custom/customer/${STRFTIME(${EPOCH},,%Y%m%d)}-${CALLERID(num)})
exten => s,n,WaitExten(5)
exten => 1,1,AGI(vblog.php,M4,${clid},${rdate},${fname}) ;Prompt call AGI to save recorded file’s information in database.
exten => 1,n,Playback(custom/B1L2_1) ;Prompt Confirming saving of the blog
exten => 1,n,Goto(mainmenu,s,1)
exten => 2,1,Goto(menu-1,s,1)
exten => i,1,Playback(custom/invalid) ;prompt Invalid choice
exten => i,n,Goto(menu-1,s,1)
exten => t,1,Goto(menu-1,s,1)
exten => h,1,Set(CDR(userfield)=${br})
;Menu 2
exten => s,1,Read(mobileno,custom/B2L1,11,,3,5) ;Prompt please enter mobile no
exten => s,n,GotoIf($[“${READSTATUS}” = “TIMEOUT”]?s,1)
exten => s,n,Set(br=${br}2-)
exten => s,n,Playback(custom/B2L2) ;Prompt you have entered
exten => s,n,SayDigits(${mobileno}) ;Prompt read the entered mobile no
exten => s,n,Set(TIMEOUT(response)=10)
exten => s,n,Set(TIMEOUT(digit)=1)
exten => s,n,Background(custom/B2L2_1) ;Prompt Confirm Mobile no, 1-OK, 2-ask again from mobile no
exten => s,n,WaitExten()
exten => i,1,Playback(custom/invalid) ;Prompt Invalid Choice
exten => i,n,Goto(s,mainmenu)
exten => t,1,Goto(s,mainmenu)
exten => h,1,Set(CDR(userfield)=${br})
exten => 0,1,Goto(mainmenu,s,1)
exten => 1,1,Goto(menu-2-1,s,1)
exten => 2,1,Goto(menu-2,s,1)
exten => s,1,Set(TIMEOUT(response)=15)
exten => s,n,Set(TIMEOUT(digit)=1)
exten => s,n,Set(br=${br}1-)
exten => s,n,Background(custom/B2_1L1) ;Prompt “Now you will hear your friend’s blog, Press 1 = Confirm, 2 – Main menu”
exten => s,n,WaitExten()
exten => 1,1,AGI(kothabarta.php,M3,${mobileno})
exten => 1,n,GotoIf($[${fname}=0]?err)
exten => 1,n,Playback(custom/customer/${fname})
exten => 1,n,Playback(beep)
exten => 1,n,Goto(mainmenu,s,1)
exten => 1,n(err),Playback(custom/B2_1L2) ;Prompt “You friend does not record any blog”
exten => 1,n,Goto(menu-2,s,1)
exten => 2,1,Goto(mainmenu,s,1)
exten => i,1,Playback(custom/invalid)
exten => i,n,Goto(s,mainmenu,1)
exten => t,1,Goto(s,mainmenu,1)
exten => h,1,Set(CDR(userfield)=${br})

Now that we have the dial plan done, we need create vblog.php file to handle AGI calls and perform database manipulation.

#!/usr/bin/php -q
require ‘phpagi.php’;
$agi = new AGI();

// DB connect
$db = ‘<your dbname>’;
$user = ‘<username>’;
$pass = ‘<password>’;
$host = ‘<hostname>’;

$mysqli = new mysqli($host, $user, $pass, $db);


// check connection
if (mysqli_connect_errno()) {
    echo “Connect failed: %s\n”, mysqli_connect_error();
        $agi->set_variable(“dberr”, “1”);

if ($d==”M3″){
        $result = $mysqli->query(“select rec_file_name from voice_rec where caller_id = ‘$mn'”);
        $num_row = mysqli_num_rows($result);
        if ($num_row == 0){
                $agi->set_variable(“fname”, 0);
        } else {
                while ($row = $result->fetch_array()){
                        $agi->set_variable(“fname”, $row[‘rec_file_name’]);
} elseif ($d==”M4″){
        $result = $mysqli->query(“select rec_file_name from voice_rec where  caller_id = ‘$c_id'”);
        $num_row = mysqli_num_rows($result);
        if ($num_row == 0){
                $agi->set_variable(“resp”, $num_row);
                $mysqli->query(“INSERT INTO voice_rec(caller_id,rec_date,rec_file_name) values (‘$c_id’,’$rd’,’$fn’)”);
        } else {
                 $mysqli->query(“update voice_rec set rec_date = ‘$rd’, rec_file_name = ‘$fn’, approved = null, c_like = 0 where caller_id = ‘$c_id'”);
                 $agi->set_variable(“resp”,D );

So the vBlog application access code is 100. When the call comes in, caller will hear the welcome and ask for menu choice. For menu one, caller will be given option to record his/her message, the same will be played back to him/her and will be asked for confirmation before saving the recorded voice file. On callers confirmation, AGI will perform the DB manipulation.

Using the same table structure more functionalities can be added.

  1. Put an admin approval process before publishing the blog.
  2. Like friends blog.
  3. Listen most liked blogs.
  4. Listen live count of your own blog.


That’s all folks……..!



About Mamun Shaheed

I love to imagine....I guess thats the only thing that keeps me going and going and going....
This entry was posted in Asterisk, IP PBX, IVR and tagged , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s