The Guru Of Tech - Gobind

Asterisk Insall, Codec Install, Vicidial Install.

Vicidial, Asterisk, Web-MeetMe, MySQL, OTRS

Vicidial, Asterisk, Web-MeetMe, MySQL, OTRS

Vicidial, Asterisk, Web-MeetMe, MySQL, OTRS

Vicidial, Asterisk, Web-MeetMe, MySQL, OTRS.

Vicidial, Asterisk, Web-MeetMe, MySQL, OTRS

Vicidial, Asterisk, Web-MeetMe, MySQL, OTRS.

Saturday, September 22, 2012

Keeping putty idle sessions active.

Another frustrating problem is induced by the time-to-live of inactive or idle TCP sessions on firewall or switch configurations. At some companies this is put aggressively low so that TCP sessions that have no activity for 1 minute or even 30 seconds are being dropped. If you are using an SSH connection over such a network device, you have to take care to send keep-alive packets over your idle session.

To do this

go to Category: Connection and set Seconds between keepalives (0 to turn off) to 25.

You Are DONE!!

Friday, September 21, 2012

Guide to install Web-MeetMe. by Sunny Khetarpal

1. Download and extract Web-MeetMe gui in the root direcotry of your
Web Server (usually /var/www/). The actual version of the package is
1.3.3. Run :
wget http://www.fitawi.com/Asterisk/Web-MeetMe_v1.3.3.tgz
As root run:
cd /var/www/
mv Web-MeetMe_v1.3.3.tgz /var/www/
tar -xzf Web-MeetMe_v1.3.3.tgz
mv Web-MeetMe web-meetme (it's not necessary, if you do this you'll
have to edit the index.html file in the same folder in order to match
the address)


2. Edit the file Web-MeetMe/lib/defines.php in order to match the
configuration of your system ( database configuration). Here is an
example of the configurable part of the file with some comment.

define ("WEBROOT", "http://192.168.0.1/");
// IP address of you asterisk server
define ("FSROOT", "/var/www/Web-MeetMe/");
// Absolute address of the folder where the package was extracted
define ("LIBDIR", FSROOT."lib/");
define ("HOST", "localhost");
// Server alias
define ("PORT", "3306");
// The standard port used by Asterisk is 3306
define ("USER", "root");
define ("PASS", "");
// Username and password of your database.
//Default password for mysql if it was installed by asterisk@home is
//passw0rd, otherwise the default password for root user in a normal
//mysql installation is empty ("").
// It's really dangerous use default password for an obvious security
//issue.
define ("DBNAME", "meetme");
// Database name. Don't change if you want to follow this guide.
define ("DB_TYPE", "mysql"); // mysql o postgres
//This guide is for mysql but can easily be adaptable to postgresql.
// Comment the following three lines if you don't want any kind of
// authentication (every user can handle or delete the conference of
// another user). The only authentication method supported by now is
// based on an Active Directory Server.
define ("AUTH_TYPE", "adLDAP"); // adLDAP or ""
define ("ADMIN_GROUP", "Domain Admins");
include (FSROOT."lib/".AUTH_TYPE.".php");
// In order to configure your Active Directory Server parameters you
// have to edit /lib/adLDAP.php
define ("DB_TABLECDR", "cdr");
define ("DB_TABLESCHED", "booking");
// Name of two tables used by the program. Don't change if you don't
//have any partucoular aim.

3. Download and compile app_cbmysql in /usr/src/asterisk/apps or
wherever you have the Asterisk source. Run as root:
cd /usr/src/asterisk/apps
wget http://www.fitawi.com/Asterisk/app_cbmysql.c
Edit the Makefile in that folder using the patch
www.fitawi.com/Asterisk/Makefile-cbmysql-patch.txt . Compile Asterisk
: run make install in the Asterisk source directory (not the
subdirectory apps!!!!). In this way you will compile only
app_cbmysql.c and not all the other parts of Asterisk.

Note: A comman error is: /usr/bin/ld: cannot find -lpq. You can avoid
this error installin the package postgresql-devel (or the equivalent
of your distribution). You have to install it even if you will use
mysql as database.

4. Create the database meetme and the table booking folling the file
www.fitawi.com/Asterisk/db-tables-v2.txt. Here is the sql code used to
create the table.

CREATE TABLE `booking` (
`bookId` INT( 11 ) DEFAULT NULL NOT NULL AUTO_INCREMENT ,
`clientId` INT( 11 ) DEFAULT '0' NOT NULL ,
`roomNo` VARCHAR( 30 ) DEFAULT '0' NOT NULL ,
`roomPass` VARCHAR( 30 ) DEFAULT '0' NOT NULL ,
`silPass` VARCHAR( 30 ) DEFAULT '0' NOT NULL ,
`startTime` DATETIME DEFAULT '0000-00-00 00:00:00' NOT NULL ,
`endTime` DATETIME DEFAULT '0000-00-00 00:00:00',
`dateReq` DATETIME DEFAULT '0000-00-00 00:00:00' NOT NULL ,
`dateMod` DATETIME DEFAULT '0000-00-00 00:00:00' NOT NULL ,
`maxUser` VARCHAR( 30 ) DEFAULT '10' NOT NULL ,
`status` VARCHAR( 30 ) DEFAULT 'A' NOT NULL ,
`confOwner` VARCHAR( 30 ) NOT NULL ,
`confDesc` VARCHAR( 30 ) NOT NULL ,
PRIMARY KEY ( `bookId` )
);


5. Download cbmysql.conf and copy it in /etc/asterisk. Run:
cd /etc/asterisk
wget http://www.fitawi.com/Asterisk/cbmysql.conf
Edit with your system parameters. A possible configuration is:
[global]
hostname=localhost
dbname=meetme
password=
user=root
port=3306
// database port, the same used in defines.php
sock=/var/run/mysqld/mysqld.sock
//Where the used socket is. Default path is ok for red hat flavour
while Debian (and his flavors like Ubuntu) has that file in
/var/run/mysqld/mysqld.sock
OptsAdm=dp
OptsUsr=dp
ConfApp=MeetMe
ConfAppCount=MeetMeCount

6. Edit /etc/asterisk/manager.conf
It's necessary to enable the global user and create the phpagi one if
it's not already present adding this code:
[phpagi]
secret = phpagi
deny=0.0.0.0/0.0.0.0
permit=127.0.0.1/255.255.255.0

read = system,call,log,verbose,command,agent,user
write = system,call,log,verbose,command,agent,user
It's dangerous to leave default password (in every cas). In order to
chacge it you have to use the same password in manager.conf and in
phpagi.conf in /etc/asterisk.
If that file not exist you have to create it editing
phpagi.example.conf in ../Web-MeetMe/phpagi/ .

7. Edit extensions.conf. You can add:
exten => 8600,1,Answer
exten => 8600,2,Wait(1)
exten => 8600,3,CBMysql()
exten => 8600,4,Hangup

8. Check if you have "register_globals = On" in php.ini and the line
"extension=mysql.so" have to be not commented.

9.Reload Asterisk.

Wednesday, September 12, 2012

How to delete all the files from the directory in PHP

<?PHP

emptyDir("/home/DIR_NAME/public_html");

FUNCTION emptyDir($path) {

// init the debug string
$debugStr = '';
$debugStr .= "DeletingContents Of: $path<br /><br />";

// parse the folder
IF ($handle = OPENDIR($path)) {

WHILE (FALSE !== ($file = READDIR($handle))) {

IF ($file != "." && $file != "..") {

// If it's a file, delete it
IF(IS_FILE($path."/".$file)) {

IF(UNLINK($path."/".$file)) {
$debugStr .= "Deleted File: ".$file."<br />";
}

} ELSE {

// It's a directory...
// crawl through the directory and delete the
contents
IF($handle2 = OPENDIR($path."/".$file)) {

WHILE (FALSE !== ($file2 = READDIR($handle2))) {

IF ($file2 != "." && $file2 != "..") {
IF(UNLINK($path."/".$file."/".$file2)) {
$debugStr .= "Deleted File:
$file/$file2<br />";
}
}

}

}

IF(RMDIR($path."/".$file)) {
$debugStr .= "Directory: ".$file."<br />";
}

}

}

}

}
RETURN $debugStr;
}

Monday, August 13, 2012

Generate XML from MySQL database via PHP

<?php

mysql_connect('localhost', 'root', 'admin');
mysql_select_db('xml');

$sql = "SELECT udid, country,code FROM country ORDER BY udid";
$res = mysql_query($sql);

$xml = new XMLWriter();

$xml->openURI("php://output");
$xml->startDocument();
$xml->setIndent(true);

$xml->startElement('countries');

while ($row = mysql_fetch_assoc($res)) {


   $xml->startElement("udid");
   $xml->writeRaw($row['udid']);
   $xml->endElement();
 
 
   $xml->startElement("country");
   $xml->writeAttribute('udid', $row['udid']);
   $xml->writeRaw($row['country']);
   $xml->endElement();
 
  $xml->startElement("code");
  $xml->writeRaw($row['code']);
  $xml->endElement();
 
}

$xml->endElement();

header('Content-type: text/xml');
$xml->flush();

?>

Thursday, June 21, 2012

Sending Email From the dialplan

exten => s,1,NoOp()
exten => s,n,System(echo "To: simplesunny@gmail.com" > /opt/etc/init.d/calls)
exten => s,n,System(echo "Subject: [PBX]: Service Down" >> /opt/etc/init.d/calls)
exten => s,n,System(echo "" >> /opt/etc/init.d/calls)
exten => s,n,System(echo "service down at ${STRFTIME(%C%m%d%y%H%M)}" >> /opt/etc/init.d/calls)
exten => s,n,System(sendmail -t -f noc@gmail.com < /opt/etc/init.d/calls)
exten => s,n,Hangup
sub mailSend {
my ($subj, $body) = @_;
my(@da, @day, @mon, $datetime, $expTO, $mail, $head);
@da = localtime(time);
@day = qw(Sun Mon Tue Wed Thu Fri Sat);
@mon = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
$datetime = sprintf "%s, %02d %s %d %02d:%02d:%02d +0900",
($day[$da[6]], $da[3]*1, $mon[$da[4]], $da[5]+1900,
$da[2]*1, $da[1]*1, $da[0]*1);
$body = Jcode->new($body)->h2z->jis;
$head = "Return-Path: <$m_RETPATH>\n";
$expTO = join(",\n ", @m_MAILTO);
$head .= "To: $expTO\n";
$head .= "From: $m_FROM\n";
$head .= "Date: $datetime\n";
$head .= "Content-type: text/plain; charset=iso-2022-jp\n";
$head .= "Subject: $subj\n";
$head .= "\n";
$head = &mimeencode($head);
$mail = "$head$body";
if (open (OUT, "|$QIPATH")) { # qmail-inject
$mail =~ s/%/%%/g;
printf OUT "$mail";
close (OUT);
}
}
Another Way-à

exten => 1234,1,Answer
exten => 1234,2,System(echo "Service Down" | mail -s "SUBJECT" simplesunny@gmail.com)
Exten => alarm,1,System(/usr/local/bin/sendalarm.sh|email at address.com)
Another Way-à
Exten => alarm,1,AGI(sendalarm)
/usr/local/bin/sendalarm
#!/bin/sh
Mail -s "Alarm condition on PBX" $1 < /dev/null

Friday, June 1, 2012

Backup Your MySQL Database Using PHP

One of the most important tasks any developer needs to do often is back up their MySQL database. In many cases, the database is what drives most of the site. While most web hosts do a daily backup of a customer's database, relying on them to make backups and provide them at no cost is risky to say the least. That's why I've created a database backup function that I can call whenever I want -- including nightly CRONs.

The PHP & MySQL Code

backup_tables('localhost','username','password','databasename');
 
 
/* backup the db OR just a table */
function backup_tables($host,$user,$pass,$name,$tables = '*')
{
  
  $link = mysql_connect($host,$user,$pass);
  mysql_select_db($name,$link);
  
  //get all of the tables
  if($tables == '*')
  {
    $tables = array();
    $result = mysql_query('SHOW TABLES');
    while($row = mysql_fetch_row($result))
    {
      $tables[] = $row[0];
    }
  }
  else
  {
    $tables = is_array($tables) ? $tables : explode(',',$tables);
  }
  
  //cycle through
  foreach($tables as $table)
  {
    $result = mysql_query('SELECT * FROM '.$table);
    $num_fields = mysql_num_fields($result);
    
    $return.= 'DROP TABLE '.$table.';';
    $row2 = mysql_fetch_row(mysql_query('SHOW CREATE TABLE '.$table));
    $return.= "\n\n".$row2[1].";\n\n";
    
    for ($i = 0; $i < $num_fields; $i++) 
    {
      while($row = mysql_fetch_row($result))
      {
        $return.= 'INSERT INTO '.$table.' VALUES(';
        for($j=0; $j<$num_fields; $j++) 
        {
          $row[$j] = addslashes($row[$j]);
          $row[$j] = ereg_replace("\n","\\n",$row[$j]);
          if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
          if ($j<($num_fields-1)) { $return.= ','; }
        }
        $return.= ");\n";
      }
    }
    $return.="\n\n\n";
  }
  
  //save file
  $handle = fopen('db-backup-'.time().'-'.(md5(implode(',',$tables))).'.sql','w+');
  fwrite($handle,$return);
  fclose($handle);
}

Saturday, May 19, 2012

nth occurance of a character in Excel

To find the last occurance of "," (comma) in a string in excel

=RIGHT(A1,LEN(A1)-FIND("|",SUBSTITUTE(A1,",","|",LEN(A1)-LEN(SUBSTITUTE(A1,",","")))))

This will find the last occurance of the string after the last "," (comma)

Windows 7: How to Add & Remove the Taskbar

Do you want to remove the Windows 7 taskbar from the desktop? Since the Windows 7 taskbar takes up space on the desktop, many prefer to remove the taskbar. Like other Windows operating systems, Windows 7 taskbar also includes the Start menu, shortcuts for open documents as well as programs, and notifications. After removing, if you want you can also easily add the taskbar back.


Let’s take a look at the following steps.
•  Step 1: Click “Start,” then “Control Panel,” “Appearance and Personalization” and “Taskbar and Start Menu.
•  Step 2: You need to check the box next to “Auto-hide the Taskbar” and click “OK.” This will remove the Windows 7 taskbar from your desktop.
•  Step 3: If you want to add the taskbar back, drag the cursor over the area where the Windows 7 taskbar used to be. This will display the Windows 7 taskbar.
•  Step 4: Now click “Start,” “Control Panel,” “Appearance and Personalization” and “Taskbar and Start Menu.
•  Step 5: Here you have to uncheck the box next to “Auto-hide the Taskbar.
•  Step 6: Click “OK.” This will add the Windows 7 taskbar back to your desktop.

Windows 7 GodMode


Windows 7 has a useful but hidden GodMode that displays all the operating system's administration tools and control options on a single screen, giving you instant access to settings that can customise and enhance your PC.

TO Activate GodMode

Go to Start, Computer and Select C: Drive

Right Click and Create New Folder

Highlight and Rename the Folder by pressing F2 and rename it to;
GodMode.{ED7BA470-8E54-465E-825C-99712043E01C} 
and press enter

The Folder Changes to Control Panel Icon and GodMode Options will be enabled

Thursday, April 26, 2012

Samsung Galaxy S3 manual leak


Samsung's unprecedented secrecy about the Galaxy S3 has paid off so far, despite that the days that ramp up to its May 3 unveiling saw a fair amount of leaks. 

We still haven't seen the design, but the latest unauthorized report today is a page derived from the service manual on a Samsung GT-I9300, which shows a render with a physical home button, just as rumored. A 4.8" Super AMOLED screen is listed, of the MIPI (C-type) variety, which allegedly means an HD RGB Super AMOLED.

The specs reveal an 8MP camera, like what we saw on the early GT-I9300 prototype last week, which, however, coincided with the f/2.6 aperture of the module on the Galaxy S II, so things could have changed since December when that prototype was made.

The tipsters indeed hint that this service manual is a very early version, so hopefully the camera will be the 12MP shooter that Amazon Germany and AnTuTu ranking charts are listing. The quad-core Exynos 4412 that will be in the Galaxy S3 has a proprietary Image Signal Processor, as illustrated on Samsung's Exynos blog, so we keep our hopes high on that front.


Wednesday, April 25, 2012

OTRS Using Ticket Last Updated Time Instead of Age Solution



::Printing Last Update Time On The Agent Ticket Queue View::
----------------------------------------------------------------------------------------------------
----------
Locate:
----------
Kernel\Output\HTML\Standard\AgentTicketQueueTicketView.dtl
----------
Look for:
----------
 $Env{"Box0"}$Text{"Age"}: $Data{"Age"}$Env{"Box1"}
----------
Change to:
----------
 $Env{"Box0"}$Text{"LastUpdated"}: $Data{"LastUpdated"}$Env{"Box1"}
----------
Look for:
----------
        <tr>
          <td class="mainkey">$Text{"Created"}:</td>
          <td class="mainvalue"> $TimeLong{"$Data{"AgeCreated"}"}</td>
        </tr>
----------
Change to:
----------
        <tr>
          <td class="mainkey">$Text{"Age"}:</td>
          <td class="mainvalue">&nbsp;$Data{"Age"} </td>
          <td>&nbsp;</td>
          <td class="mainkey">$Text{"Created"}:</td>
          <td class="mainvalue"> $TimeLong{"$Data{"AgeCreated"}"}</td>
        </tr>
----------
Locate:
----------
Kernel\Output\HTML\Standard\AgentTicketZoom.dtl
----------
Look for:
----------
    <td align="right" width="30%" class="mainhead">
      $Env{"Box0"}$Text{"Age"}: $Data{"Age"}$Env{"Box1"}
    </td>
----------
Change to:
----------
    <td align="right" width="30%" class="mainhead">
      $Env{"Box0"}$Text{"Updated"}: $TimeLong{"$Data{"LastUpdated"}"}$Env{"Box1"}
    </td>
----------
Look for:
----------
    <td align="right" width="30%" class="menu">
      <table border="0" cellspacing="0" cellpadding="0">
        <tr>
          <td class="mainkey">$Text{"Created"}:</td>
          <td class="mainvalue"> $TimeLong{"$Data{"Created"}"}</td>
        </tr>
      </table>
    </td>
----------
Change to:
----------
    <td align="right" width="30%" class="menu">
      <table border="0" cellspacing="0" cellpadding="0">
        <tr>
          <td class="mainkey">$Text{"Age"}:</td>
          <td class="mainvalue">&nbsp;$Data{"Age"} </td>
          <td>&nbsp;</td>
          <td class="mainkey">$Text{"Created"}:</td>
          <td class="mainvalue"> $TimeLong{"$Data{"Created"}"}</td>
        </tr>
      </table>
    </td>
----------
Locate:
----------
Kernel\System\Ticket\Article.pm
----------
Look for:
----------
        . ' st.escalation_solution_time, st.escalation_time '
----------
Change to:
----------
        . ' st.escalation_solution_time, st.escalation_time, st.change_time '
----------
Look for:
----------
        $Data{SLAID}               = $Row[75];
        $Ticket{SLAID}             = $Row[75];
----------
Change to:
----------
        $Data{SLAID}               = $Row[75];
        $Ticket{SLAID}             = $Row[75];
        $Data{LastUpdated}           = $Row[79];
        $Ticket{LastUpdated}         = $Data{LastUpdated};
        $Data{AgeCreated}            = $Self->{TimeObject}->SystemTime2TimeStamp( SystemTime => $Row[8] );
        $Ticket{AgeCreated}          = $Data{AgeCreated};
----------
Locate:
----------
Kernel\System\Ticket.pm
----------
Look for:
----------
        $Ticket{TicketFreeTime6}        = defined( $Row[53] ) ? $Row[53] : '';
----------
Change to:
----------
        $Ticket{TicketFreeTime6}        = defined( $Row[53] ) ? $Row[53] : '';
        $Ticket{LastUpdated}            = $Row[54];
        $Ticket{AgeCreated}             = $Self->{TimeObject}->SystemTime2TimeStamp( SystemTime => $Row[7] );
----------------------------------------------------------------------------------------------------
::Sort Agent Ticket Queue View By Last Updated Time::
----------------------------------------------------------------------------------------------------
----------
Locate:
----------
Kernel\Modules\AgentTicketQueue.pm
----------
Look for:
----------
        TicketFreeText16       => 'st.freetext16'
----------
Change to:
----------
        TicketFreeText16       => 'st.freetext16',
        LastUpdated            => 'st.change_time'
----------
Locate:
----------
Kernel\Config\Files\Ticket.xml
----------
Look for:
----------
        <SubGroup>Frontend::Agent::Ticket::ViewQueue</SubGroup>
        <Setting>
            <Option SelectedID="Age">
                <Item Key="Age">Age</Item>
----------
Change to:
----------
        <SubGroup>Frontend::Agent::Ticket::ViewQueue</SubGroup>
        <Setting>
            <Option SelectedID="Age">
                <Item Key="Age">Age</Item>
                <Item Key="LastUpdated">LastUpdated</Item>
----------
Note!
----------
Then select the LastUpdated option in the web interface.
Its under Admin->SysConfig->Ticket->Frontend::Agent::Ticket::ViewQueue->
Ticket::Frontend::AgentTicketQueue###SortBy::Default:
----------------------------------------------------------------------------------------------------
::Updating Last Updated Time When A Note Is Added To A Ticket::
----------------------------------------------------------------------------------------------------
----------
Locate:
----------
Kernel\Modules\AgentTicketNote.pm
----------
Look for:
----------
    # redirect to last screen overview on closed tickets
    if ( $StateData{TypeName} =~ /^close/i ) {
        return $Self->{LayoutObject}->Redirect( OP => $Self->{LastScreenOverview} );
    }
----------
Change to:
----------
    # redirect to last screen overview on closed tickets
    if ( $StateData{TypeName} =~ /^close/i ) {
        return $Self->{LayoutObject}->Redirect( OP => $Self->{LastScreenOverview} );
    }
    $Self->{TicketObject}->TicketUpdateTimeSet(
        UserID   => $Self->{UserID},
        TicketID => $Self->{TicketID},
        %GetParam,
    );
----------
Locate:
----------
Kernel\System\Ticket.pm
----------
Look for:
----------
=item TicketAclActionData()
return the current ACL action data hash after TicketAcl()
    my %AclAction = $TicketObject->TicketAclActionData();
=cut
sub TicketAclActionData {
    my ( $Self, %Param ) = @_;
    if ( $Self->{TicketAclActionData} ) {
        return %{ $Self->{TicketAclActionData} };
    }
    else {
        return %{ $Self->{ConfigObject}->Get('TicketACL::Default::Action') };
    }
}
----------
Change to:
----------
=item TicketAclActionData()
return the current ACL action data hash after TicketAcl()
    my %AclAction = $TicketObject->TicketAclActionData();
=cut
sub TicketAclActionData {
    my ( $Self, %Param ) = @_;
    if ( $Self->{TicketAclActionData} ) {
        return %{ $Self->{TicketAclActionData} };
    }
    else {
        return %{ $Self->{ConfigObject}->Get('TicketACL::Default::Action') };
    }
}
=item TicketUpdateTimeSet()
set ticket update time
    $TicketObject->TicketUpdateTimeSet(
        Year     => 2003,
        Month    => 08,
        Day      => 14,
        Hour     => 22,
        Minute   => 05,
        TicketID => 123,
        UserID   => 23,
    );
or use a time stamp
    $TicketObject->TicketUpdateTimeSet(
        String   => '2003-08-14 22:05:00',
        TicketID => 123,
        UserID   => 23,
    );
=cut
sub TicketUpdateTimeSet {
    my ( $Self, %Param ) = @_;
    my $Time;
    # check needed stuff
    if ( !$Param{String} ) {
        for (qw(Year Month Day Hour Minute TicketID UserID)) {
            if ( !defined $Param{$_} ) {
                $Self->{LogObject}->Log( Priority => 'error', Message => "Need $_!" );
                return;
            }
        }
    }
    # get system time from string/params
    if ( $Param{String} ) {
        $Time = $Self->{TimeObject}->TimeStamp2SystemTime( String => $Param{String}, );
        ( $Param{Sec}, $Param{Minute}, $Param{Hour}, $Param{Day}, $Param{Month}, $Param{Year} )
            = $Self->{TimeObject}->SystemTime2Date( SystemTime => $Time, );
    }
    else {
        $Time = $Self->{TimeObject}->TimeStamp2SystemTime(
            String => "$Param{Year}-$Param{Month}-$Param{Day} $Param{Hour}:$Param{Minute}:00",
        );
    }
    # return if no convert is possible
    if ( !$Time ) {
        return;
    }
    # db update
    return if !$Self->{DBObject}->Do(
        SQL => 'UPDATE ticket SET '
            . ' change_time = current_timestamp, change_by = ? WHERE id = ?',
        Bind => [ \$Param{UserID}, \$Param{TicketID} ],
    );
    # clear ticket cache
    delete $Self->{ 'Cache::GetTicket' . $Param{TicketID} };
    # ticket event
    $Self->TicketEventHandlerPost(
        Event    => 'TicketUpdateTimeUpdate',
        UserID   => $Param{UserID},
        TicketID => $Param{TicketID},
    );
    return 1;
}
----------
Look for:
----------
=item TicketEventHandlerPost()
call ticket event post handler, returns true if it's executed successfully
    $TicketObject->TicketEventHandlerPost(
        TicketID => 123,
        Event    => 'TicketStateUpdate',
        UserID   => 123,
    );
events available:
TicketCreate, TicketDelete, TicketTitleUpdate, TicketUnlockTimeoutUpdate,
TicketQueueUpdate, TicketTypeUpdate, TicketServiceUpdate,
TicketSLAUpdate, TicketCustomerUpdate, TicketFreeTextUpdate, TicketFreeTimeUpdate,
TicketPendingTimeUpdate, TicketLockUpdate, TicketStateUpdate, TicketOwnerUpdate,
TicketResponsibleUpdate, TicketPriorityUpdate, HistoryAdd, HistoryDelete,
TicketAccountTime, TicketMerge, ArticleCreate, ArticleFreeTextUpdate,
ArticleUpdate, ArticleSend, ArticleBounce, ArticleAgentNotification,
ArticleCustomerNotification, ArticleAutoResponse, ArticleFlagSet, ArticleFlagDelete;
----------
Change to:
----------
=item TicketEventHandlerPost()
call ticket event post handler, returns true if it's executed successfully
    $TicketObject->TicketEventHandlerPost(
        TicketID => 123,
        Event    => 'TicketStateUpdate',
        UserID   => 123,
    );
events available:
TicketCreate, TicketDelete, TicketTitleUpdate, TicketUnlockTimeoutUpdate,
TicketQueueUpdate, TicketTypeUpdate, TicketServiceUpdate,
TicketSLAUpdate, TicketCustomerUpdate, TicketFreeTextUpdate, TicketFreeTimeUpdate,
TicketPendingTimeUpdate, TicketLockUpdate, TicketStateUpdate, TicketOwnerUpdate,
TicketResponsibleUpdate, TicketPriorityUpdate, HistoryAdd, HistoryDelete,
TicketAccountTime, TicketMerge, ArticleCreate, ArticleFreeTextUpdate,
ArticleUpdate, ArticleSend, ArticleBounce, ArticleAgentNotification,
ArticleCustomerNotification, ArticleAutoResponse, ArticleFlagSet, ArticleFlagDelete, TicketUpdateTimeUpdate;
----------
Look for:
----------
        elsif ( $Param{Event} eq 'ArticleAutoResponse' ) {
            $Param{Event} = 'SendAutoResponse';
        }
        else {
            return 1;
        }
----------
Change to:
----------
        elsif ( $Param{Event} eq 'ArticleAutoResponse' ) {
            $Param{Event} = 'SendAutoResponse';
        }
        elsif ( $Param{Event} eq 'TicketUpdateTimeUpdate' ) {
            $Param{Event} = 'TicketUpdateTimeSet';
        }
        else {
            return 1;
        }
----------------------------------------------------------------------------------------------------
::Updating Last Updated Time When A Phone Reply Is Added To A Ticket::
----------------------------------------------------------------------------------------------------
----------
Locate:
----------
Kernel\Modules\AgentTicketPhoneOutbound.pm
----------
Look for:
----------
        # should i set an unlock? yes if the ticket is closed
----------
Change to:
----------
        # set last updated time
        $Self->{TicketObject}->TicketUpdateTimeSet(
            UserID   => $Self->{UserID},
            TicketID => $Self->{TicketID},
            %GetParam,
        );
        # should i set an unlock? yes if the ticket is closed
----------------------------------------------------------------------------------------------------
::Display Accounted Time Units On Customer Screen::
----------------------------------------------------------------------------------------------------
----------
Locate:
----------
Kernel\Modules\CustomerTicketOverview.pm
----------
Look for:
----------
    # condense down the subject
----------
Change to:
----------
    my $WorkTime = $Self->{TicketObject}->TicketAccountedTimeGet(TicketID => $Param{TicketID});
    # condense down the subject
----------
Look for:
----------
    # add block
    $Self->{LayoutObject}->Block(
        Name => 'Record',
        Data => {
            %Article,
            Subject => $Subject,
            %Param,
----------
Change to:
----------
    # add block
    $Self->{LayoutObject}->Block(
        Name => 'Record',
        Data => {
            %Article,
            Subject => $Subject,
            WorkTime => $WorkTime,
            %Param,
----------
Locate:
----------
Kernel\Output\HTML\Standard\CustomerStatusView.dtl
----------
Look for:
----------
          <th width="10%">$Text{"Owner"}<br/>
          <a href="$Env{"Baselink"}Action=$Env{"Action"}&SortBy=Owner&Order=Up&Limit=$Data{"Limit"}&ShowClosedTickets=$Data{"ShowClosed"}&Type=$Data{"Type"}" onmouseover="window.status='$JSText{"sort upward"}'; return true;" onmouseout="window.status='';"><img border="0" src="$Env{"Images"}up-small.png" alt="$Text{"up"}"></a> /
          <a href="$Env{"Baselink"}Action=$Env{"Action"}&SortBy=Owner&Order=Down&Limit=$Data{"Limit"}&ShowClosedTickets=$Data{"ShowClosed"}&Type=$Data{"Type"}" onmouseover="window.status='$JSText{"sort downward"}'; return true;" onmouseout="window.status='';"><img border="0" src="$Env{"Images"}down-small.png" alt="$Text{"down"}"></a>
          </th>
----------
Change to:
----------
          <th width="5%">$Text{"Owner"}<br/>
          <a href="$Env{"Baselink"}Action=$Env{"Action"}&SortBy=Owner&Order=Up&Limit=$Data{"Limit"}&ShowClosedTickets=$Data{"ShowClosed"}&Type=$Data{"Type"}" onmouseover="window.status='$JSText{"sort upward"}'; return true;" onmouseout="window.status='';"><img border="0" src="$Env{"Images"}up-small.png" alt="$Text{"up"}"></a> /
          <a href="$Env{"Baselink"}Action=$Env{"Action"}&SortBy=Owner&Order=Down&Limit=$Data{"Limit"}&ShowClosedTickets=$Data{"ShowClosed"}&Type=$Data{"Type"}" onmouseover="window.status='$JSText{"sort downward"}'; return true;" onmouseout="window.status='';"><img border="0" src="$Env{"Images"}down-small.png" alt="$Text{"down"}"></a>
          </th>
          <th width="5%">$Text{"Time"}</th>
----------
Look for:
----------
          <td class="$Env{"Color"}"><div title="$Quote{"$Data{"Owner"}"}">$Quote{"$Data{"Owner"}","18"}</div></td>
----------
Change to:
----------
          <td class="$Env{"Color"}"><div title="$Quote{"$Data{"Owner"}"}">$Quote{"$Data{"Owner"}","18"}</div></td>
          <td class="$Env{"Color"}">$QData{"WorkTime"}</td>
----------------------------------------------------------------------------------------------------
::Printing Last Update Time On The Customer Ticket Zoom::
----------------------------------------------------------------------------------------------------
----------
Locate:
----------
Kernel\Output\HTML\Standard\CustomerTicketZoom.dtl
----------
Look for:
----------
<table border="0" width="100%" cellspacing="0" cellpadding="3">
  <tr>
    <td width="50%" class="mainhead">
      $Env{"Box0"}$Text{"Zoom"} $Config{"Ticket::Hook"}: $Data{"TicketNumber"}$Env{"Box1"}
    </td>
    <td align="right" width="50%" class="mainhead">
      $Env{"Box0"}$Text{"Age"}: $Data{"Age"}$Env{"Box1"}
    </td>
  </tr>
</table>
<table border="0" width="100%" cellspacing="0" cellpadding="3">
  <tr>
    <td width="70%" class="menu">
      <a href="$Env{"Baselink"}Action=CustomerTicketPrint&TicketID=$QData{"TicketID"}" onmouseover="window.status='$JSText{"Print Ticket"}'; return true;" onmouseout="window.status='';" target="_blank">$Text{"Print"}</a>
    </td>
    <td align="right" width="30%" class="menu">
      <b>$Text{"Created"}:</b> $TimeLong{"$Data{"Created"}"}
    </td>
  </tr>
</table>
----------
Change to:
----------
<table border="0" width="100%" cellspacing="0" cellpadding="3">
  <tr>
    <td width="50%" class="mainhead">
      $Env{"Box0"}$Text{"Zoom"} $Config{"Ticket::Hook"}: $Data{"TicketNumber"}$Env{"Box1"}
    </td>
    <td align="right" width="50%" class="mainhead">
      $Env{"Box0"}$Text{"Updated"}: $TimeLong{"$Data{"LastUpdated"}"}$Env{"Box1"}
    </td>
  </tr>
</table>
<table border="0" width="100%" cellspacing="0" cellpadding="3">
  <tr>
    <td width="60%" class="menu">
      <a href="$Env{"Baselink"}Action=CustomerTicketPrint&TicketID=$QData{"TicketID"}" onmouseover="window.status='$JSText{"Print Ticket"}'; return true;" onmouseout="window.status='';" target="_blank">$Text{"Print"}</a>
    </td>
    <td align="right" width="40%" class="menu">
      <b>$Text{"Age"}:</b> $Data{"Age"} <b>$Text{"Created"}:</b> $TimeLong{"$Data{"Created"}"}
    </td>
  </tr>
</table>
----------------------------------------------------------------------------------------------------
::Printing Last Update Time On The Customer Screen::
----------------------------------------------------------------------------------------------------
----------
Locate:
----------
Kernel\Output\HTML\Standard\CustomerStatusView.dtl
----------
Look for:
----------
          <th width="20%">$Text{"Age"}<br/>
----------
Change to:
----------
          <th width="20%">$Text{"Updated"}<br/>
----------
Look for:
----------
          <td class="$Env{"Color"}">$QData{"Age","20"}</td>
----------
Change to:
----------
          <td class="$Env{"Color"}">$TimeLong{"$QData{"LastUpdated","20"}"}</td>
----------------------------------------------------------------------------------------------------
::Show Latest Update (regardless of who its by) on Agent Ticket Queue View::
----------------------------------------------------------------------------------------------------
----------
Locate:
----------
Kernel\System\Ticket\Article.pm
----------
Look for:
----------
    # check if latest article is sent to customer
    elsif (
        $Param{SenderType} eq 'agent'
        && $Param{ArticleType} =~ /email-ext|phone|fax|sms|note-ext/
----------
Change to:
----------
    # check if latest article is sent to customer
    elsif (
        $Param{SenderType} eq 'agent'
#        && $Param{ArticleType} =~ /email-ext|phone|fax|sms|note-ext/
#NOTE: I don't remember why this needed to be removed, but it works this way
----------
Look for:
----------
    # return ArticleID
    return $ArticleID;
}
# just for internal use
----------
Change to:
----------
    $Self->{DBObject}->Do(
        SQL => 'UPDATE ticket SET change_time = current_timestamp WHERE id = ?',
        Bind => [ \$Param{TicketID} ],
    );
    # return ArticleID
    return $ArticleID;
}
# just for internal use
----------
Look for:
----------
    # if we got no internal article, return the latest one
    return $Self->ArticleGet( ArticleID => $Index[-1] );
}
----------
Change to:
----------
    # if we got no internal article, return the latest one
    return $Self->ArticleGet( ArticleID => $Index[-1] );
}
=item ArticleLastArticle()
get last customer article
    my %Article = $TicketObject->ArticleLastArticle(
        TicketID => 123,
    );
=cut
sub ArticleLastArticle {
    my ( $Self, %Param ) = @_;
    # check needed stuff
    if ( !$Param{TicketID} ) {
        $Self->{LogObject}->Log( Priority => 'error', Message => "Need TicketID!" );
        return;
    }
    # get article index
    my @Index = $Self->ArticleIndex( TicketID => $Param{TicketID} );
    # get article data
    return $Self->ArticleGet( ArticleID => $Index[-1] ) if @Index;
    @Index = $Self->ArticleIndex( TicketID => $Param{TicketID} );
    if ( !@Index ) {
        $Self->{LogObject}->Log(
            Priority => 'error',
            Message  => "No article found for TicketID $Param{TicketID}!",
        );
        return;
    }
    # return latest non internal article
    return $Self->ArticleGet( ArticleID => $Index[-1] );
}
----------
Locate:
----------
Kernel\Modules\AgentTicketQueue.pm
----------
Look for:
----------
    # get last article
    my %Article = $Self->{TicketObject}->ArticleLastCustomerArticle( TicketID => $TicketID );
----------
Change to:
----------
    # get last article
    my %Article = $Self->{TicketObject}->ArticleLastArticle( TicketID => $TicketID );


Thursday, March 29, 2012

36 Great free Asterisk applications

Hi, I was looking round on the Internet and saw there was no definitive list of free applications available for use with Asterisk, so I thought I'd compile a list for you all. If there's anything that you know of that is actively maintained but not in the list below, let me know (bear in mind I'm not including distros or Asterisk packagings in this list).

Hopefully there are a few programs in the list that even the most seasoned Asterisk professionals have not seen before.

Flash Operator Panel

Flash Operator Panel is a switchboard type application for the Asterisk PBX. It runs on a web browser with the flash plugin. It is able to display information about your PBX activity in real time. The layout is configurable (button sizes and colors, icons, etc). You can have more than 100 buttons active per screen. On the Live Demo there are 28 buttons defined. It also supports contexts: you can have one server running and many different client displays (for hosted PBX, different departments, etc). It can integrate with CRM software, by poping up a web page (and passing the CLID) when a specified button is ringing.

PHP AGI

AGI (Asterisk Gateway Interface) is a way of running programs or scripts which are external to Asterisk. PHP AGI is a library for PHP which simplifies writing AGI scripts.

Web Meetme

Web-MeetMe is a suite of PHP pages to allow for scheduling and managing conferences on an Asterisk PBX.

Oreka

Oreka is a modular and cross-platform system for recording and retrieval of audio streams. The project currently supports VoIP and sound device based capture. Recordings metadata can be stored in any mainstream database. Retrieval of captured sessions is web based.

FreePBX
FreePBX is a full-featured PBX web application. If you've looked into Asterisk, you know that it doesn't come with any "built in" programming. You can't plug a phone into it and make it work without editing configuration files, writing dialplans, and various messing about.

FreePBX simplifies this by giving you pre-programmed functionality accessible by a user-friendly web interfaces that allows you to have a fully functional PBX pretty much straight away with no programming required.

FreePBX also comes as a distro

Areski CDR Stats

Asterisk-Stat is a visualisation layer for Asterisk CDR statistics which are pulled from a database. It provides graphs as well as allowing you to get more information on individual calls.





sipsak

sipsak is a small command line tool for developers and administrators of Session Initiation Protocol (SIP) applications. It can be used for some simple tests on SIP applications and devices.

Asterisk PhoneBook

A common shared phone book directory based on CMS/LAMP and build for Asterisk PBX, store name and number into MySQL which will be used by each workstation browser, also by telephones with embedded XML-browser feature.

Asterisk Desktop Assistant

Asterisk Desktop Assistant is a desktop call management application for Windows PCs.  Asterisk Desktop Assistant (ADA) is Digium?s first step towards offering a comprehensive Computer Telephony Integration (CTI) suite.  It makes dialing and handling phone calls simpler and faster by adding click-to-call functionality into popular desktop applications.  It also adds call notifications directly to the Windows desktop.

A2Billing

A2Billing combined with Asterisk now gives any Telecom company a very good reason to consider the A2Billing Soft-Switch over the traditional offerings for TDM and VoIP Soft-Switches as well as wholesale and IP PBX billing, particularly when you consider the cost of A2Billing ? FREE!

AstBill

AstBill is not only a free web-based, user friendly billing interface for Asterisk and VOIP. It is also a Asterisk configuration and GUI management tool and a standardized implementation of Asterisk using REALTIME and static configuration as you please.

OSLEC

Oslec is an open source high performance line echo canceller. When used with Asterisk it works well on lines where the built-in Zaptel echo canceller fails. No tweaks like rxgain/txgain or fxotrain are required. Oslec is supplied as GPL licensed C source code and is free as in speech.

Oslec partially complies with the G168 standard and runs in real time on x86 and Blackfin platforms. Patches exist to allow any Zaptel or DAHDI compatible hardware to use Oslec. It has been successfully tested on hardware ranging from single port X100P FXO cards to dual E1 systems.

AppKonference

AppKonference is a high-performance Asterisk voice/video conferencing module. It's basically a drop in replacement for meetme - although does things a little differently and doesn't require a timing source.

OutCall

OutCALL was designed as a commercial appplication allowing Asterisk users integration with Microsoft Outlook with placing and receiving phone calls.

After over 1000 downloads as a free application, Bicom Systems Ltd. has decided to offer OutCALL in open source format in order to further stimulate development of Asterisk and related open source projects.

VMukti

VMukti is leading Asterisk/ Yate enabled p2p Video IP Communications Suite for Web / PSTN. These serverless broadband ready platform enable OS community to save 90% on capital & operating costs over proprietary software for conferencing & Call Center.

Note from editor: I've personally never managed to get this working - drop me a line if you do get it all set up and going.

Asterisk-CRM

asterCRM is a call center software for asterisk based VoIP system, also it has some CRM functions. It provides useful features such as pop-up, predictive dialer, click to call, extension status .... astercrm could work with all asterisk based system.

AsterCC

astercc is a realtime billing solution for asterisk, could work with all kinds of asterisk based system and no need do any change to your original system. astercc could be used for hosted callshop solution, pbx billing solution.

IAXModem

IAXmodem is a software modem written in C that uses an IAX channel (commonly provided by an Asterisk PBX system) instead of a traditional phone line and uses a DSP library instead of DSP hardware chipsets.

Asterisk PBX Integration Zimlet

Asterisk PBX Integration Zimlet is an Extension for Zimbra Collaboration Suite. The Zimlet does Interface with the Asterisk Manager Interface to integrate with Asterisk PBX. The main focus is dial-on-click for Phone numbers inside Contacts and Emails.

AsterFax - Asterisk Email to Fax Gateway

AsterFax provides an Email to Fax gateway for Asterisk. AsterFax lets you send an email by Fax. Enter the phone no. in the 'To' address, compose your email message and click send. You can also fax a MS-Word document or other attachment.

Asterisk Monitor

Asterisk Monitor is a HTML interface that acts a operator pannel for asterisk to display user/peer status and calls. This uses a reverse AJAX, PHP and Python to originate, transfer and hangup calls, manage queues and meetme rooms.

OpenBTS
The OpenBTS Project is an effort to construct an open-source GSM basestation using the USRP and the Asterisk VoIP PBX. Our goal is to enable a new type of hybrid GSM/VoIP cellular network for greenfield deployments in the developing world.

Asterisk .NET

The Asterisk .NET library consists of a set of C# classes that allow you to easily build applications that interact with an Asterisk PBX Server (1.0/1.2/1.4 version). Both FastAGI and Manager API supported. .NET/Mono compatible.

AGX's Asterisk Extra AddOns

Maintained version of old asterisk applications ported to 1.4 that for copyright reasons cannot be included into official Digium's releases and that for some reason the author is not keeping up-to-date. The project also require Zaptel instead of DAHDI.

AstTAPI

AstTapi, an opensource Asterisk Tapi driver for windows. This allows users of TAPI compliant applications such as Outlook and Act to dial contacts directly from the application using an Asterisk PBX Server.

Asterisk-Java

A java interface for Asterisk - allows you to write software in Java which will work with Asterisk.

IAXClient

A lightweight cross platform IP telephony client using the IAX protocol, designed for use with the Asterisk open source PBX.

Asterisk Desktop Manager

A desktop application for managing Asterisk including screen pops etc - looks quite nice but haven't tried it.

Asterisk JTAPI

Asterisk-JTAPI is a JTAPI implementation for the Asterisk software PBX system. JTAPI is a provider independent programming interface for Java to build applications for computer telephony or to add support for it. JTAPI covers a wide range of usage scenarios starting from controlling a single telephone to a whole PBX system for example in call-centers.

Asterisk-JTAPI builds on top of two other projects: Asterisk-Java, which provides a Java interface to the Asterisk manager API, and, GJTAPI, which provides a general framework for JTAPI interfaces.

Astmail

Web interface to Asterisk voicemail written in php. Includes some AJAX components such as LDAP-suggest, and user-lookup. Includes screens for forward by email and sms configuration.

Druid
Druid is an open source unified communications platform, built around technology such as Asterisk, IMAP, XMPP. Druid gives your organization access to the best available IP communications platform that bringing together voicemail, VOIP, mobile phone, faxes and instant messaging.

ViciDial

VICIDIAL is a set of programs that are designed to interact with the Asterisk Open-Source PBX Phone system to act as a complete inbound/outbound call center suite.

The agent interface is an interactive set of web pages that work through a web browser to give real-time information and functionality with nothing more than an internet browser on the client computer.

Asterisk Queue/CDR Log Analyzer

The Asterisk Queue (and CDR) Log Analyzer is a set of PHP scripts which allow selecting, listing and graphing of records from the Asterisk Queue and CDR logs via a WEB interface.

For easier access to select specific log records, the Queue and CDR logs need to be in a MySQL database. Asterisk itself records (specified in a conf file) CDR data into a MySQL database table. A Python utility program called loadq.py is provided with this package which can be used to load queue log records (as they are created) into a MySQL database table.

Asterisk WEB/PHP Event Monitor

The Asterisk Event Monitor WEB/PHP Interface was created to view the current state of Asterisk and all Asterisk Events via a WEB interface. It does not poll Asterisk for these events, instead it collects them in a MySql database via an Asterisk Manager API python script. AJAX (Javascript) is used to display the events from the database almost as they occur. All code is released under the GNU GPL license.


Crystal Recording Interface

CRI (Crystal Clear Recording Interface) provides an intelligence web interface to track is recordings and his voice mail

Features :

Access your voicemail recordings.
Setup your voice mail box
View summary of your incoming outgoing calls
Search calls and recordings by day and time.
Call monitor recordings.

Xivo

XiVO is a full PBX solution based on Asterisk with a user-friendly web interface, provisioning tools for many types of phones, CTI daemon and CTI client for Windows, Linux and MacOS. All solutions are released under GPLv3. Currently only released in French, but easy to translate in other languages, XiVO provides administrators with a simple to configure phone system.

You can find a demo on https://demo.xivo.fr with login root and password proformatique so you can try it out for yourself.

On the first page you have a dashboard for monitoring all processes and you can choose PBX on the menu to administer your PBX. It's not based on Freepbx or other existing software, it's a full development from scratch.