Upgrade 3CX to v18 and get it hosted free!

PERL-SIP-AGI

Author image
// sip out going agi by imran 
#!/usr/bin/perl
use Asterisk::AGI;

my $ModuelPath 	= "/var/www/cgi-bin/modules";
my $ivrPath 		= "/var/www/html/ivrSounds";
use lib "/var/www/cgi-bin/modules";

use Db;

$AGI = new Asterisk::AGI;
my %input = $AGI->ReadParse();
my $callerid="0";
$callerid= $input{callerid};
$|=1;
$AGI->answer();

($calleridnum, $phoneno, $ZapChannel) = @ARGV;
my $g_OUTPUT;

my $C 	= $AGI->get_variable(CHANNEL);

my $tempFinalDate;
my $tempCalledNumber;
		

my %g_DATA;
my $strSQL	= "
				select 
				call_recording,
				local_calling,
				international_calling,
				international_calling_ww35,
				international_calling_all,
				call_forwarding,
				
				extension_busy,
				extension_answered,
				extension_logged,
				
				caller_id,
				summary_call,
				call_waiting,
				voice_mail,
				seconds,
				evoice
				 
				from buddies_relation
				where name=\"$phoneno\"
				";
my @Result	= Db->ExecuteQuery($strSQL);

$g_DATA{CALLRECORDING} = $Result[1][0];
$g_DATA{LOCALCALLING}  = $Result[1][1];
$g_DATA{INTCALL}			 = $Result[1][2];
$g_DATA{INTCALLWW35} 	 = $Result[1][3];
$g_DATA{INTCALLALL}    = $Result[1][4];
$g_DATA{CALLFORWARDING}= $Result[1][5];
$g_DATA{EXTBUAY}		   = $Result[1][6];
$g_DATA{EXTANSWER}	   = $Result[1][7];
$g_DATA{EXTLOG}				 = $Result[1][8];

$g_DATA{CALLERID}			 = $Result[1][9];
$g_DATA{SUMMARYCALL}	 = $Result[1][10];
$g_DATA{CALLWAITING}	 = $Result[1][11];
$g_DATA{VOICEMAIL}		 = $Result[1][12];

$g_DATA{SECONDS}		   = $Result[1][13];
$g_DATA{EVOICE}		   = $Result[1][14];

my $dial_up_to_seconds=30;


if ( $g_DATA{SECONDS} ne '' &&  $g_DATA{VOICEMAIL} eq 'Y')
{
	$dial_up_to_seconds =$g_DATA{SECONDS};
}

my @r	= Db->ExecuteQuery("select min(name), max(name) from sip_buddies");
$g_DATA{MINEXT}				 = $r[1][0];
$g_DATA{MAXEXT}				 = $r[1][1];








##### call recording feature
my $d_path	 = "/var/www/html/recordings";
my $gsm_file;
my $wav_file;
my $g_Cents;
my $answeredtime;
my $OrderId;
my $callrate;
#### end


my $recordingSize  = readRecordinSize();


if( $g_DATA{CALLRECORDING} eq 'Y' ) {
	
			$AGI->stream_file('preRecorded'); 		#PreRecorded Msg ...Recording Alert
			
			
			if( $recordingSize <= 498 ) {
													
						callrecording($phoneno);												
													
											}
			

		
	}



#$dial_up_to_seconds =30;
# - try simple simple sp dialing on extension like SIP/101
$dialstr = "SIP/".$phoneno . "|$dial_up_to_seconds|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";

##$res =$AGI->set_variable('DIALSTATUS', 'RINGING');
#$res = $AGI->exec("DIAL RINGING");
$res =$AGI->set_variable('CHANNEL', 'RINGING');
$AGI->verbose("imran ($res )\n",3);
#$AGI->wait(2);

$res = $AGI->exec("DIAL $dialstr");


# - if ANswer.. exit
my $CALLSTATUS 	= $AGI->get_variable(DIALSTATUS);

if( $CALLSTATUS eq 'ANSWER' or $CALLSTATUS eq 'ANSWERED' )
{
	 $answeredtime = $AGI->get_variable(ANSWEREDTIME);
	
	 CutBalance($OrderId,$callrate,$answeredtime);
	my $priority=4;
	$res =$AGI->set_priority($priority);
	 exit;
}

my $lineno;
my @Result;
my $is_sip =1;  # 1 mean SIP call 0 mean ZAP call

#	- do accoring to busy , unavail and 
if( ( $CALLSTATUS ne 'ANSWER' && $CALLSTATUS ne 'ANSWERED' ) && $g_DATA{CALLFORWARDING} eq 'Y')#Allow Call forwarding
{
	# its mean he can now ring on external number and as well extension number.
	
					my @Result=Db->ExecuteQuery("select co_no,outgoing_prefix  from codetail");
					my %CoPrHash;
					my $ZapStr;
				
					# /zap/1&Zap/2&Zap
					for($i=1;$i<=$#Result;$i++)
					{	
						$Co						=$Result[$i][0];
						$prefix				=$Result[$i][1];
						$CoPrHash{$Co} = $prefix;		
						$ZapStr .=	"Zap/$Co";
						if($i != $#Result)
						{
							$ZapStr .= "&"	;
						}
					}
					
					$res = $AGI->exec("ChanIsAvail $ZapStr");

	
	my	$ChannalName 		= $AGI->get_variable("AVAILCHAN"); #CHANNEL

  $ChannalName =~ /Zap\/(.*?)-/gsi;

	$lineno =$1;
	
	my $strSQL	= "
	select is_ext,info from codetail where  co_no='$lineno'";

	 @Result	= Db->ExecuteQuery($strSQL);

	if($Result[1][0] ne "")
	{	
		$AGI->stream_file('call-forward');	
		$is_sip = allowCallForwarding();
	}
	else
	{ 
		# sorry your call couldnt be forward
		$AGI->stream_file('call-forwarding');
		$AGI->stream_file('number-not-answering');
		$AGI->stream_file('sorry-youre-having-problems');
		sleep(1);
	}			
}	

# here i am checking for voice mail 
if ( $g_DATA{VOICEMAIL} eq 'Y' )
{
	#here do delay for specified number of seconds and then open the voice mail
	$CALLSTATUS 	= $AGI->get_variable(DIALSTATUS);
	
	if( ( not( $CALLSTATUS eq 'ANSWER' || $CALLSTATUS eq 'ANSWERED') ) || ($CALLSTATUS eq 'CONGESTION'))
	{
		#play a stream message for Congession and then activate the voice mail message
		$res = $AGI->exec("VoiceMail u$phoneno");	
		system("chmod +777 /var/spool/asterisk/voicemail/default/$phoneno/ -R");
		#my $priority=4;$res =$AGI->set_priority($priority);
	}
}
else
{
  if (( not( $CALLSTATUS eq 'ANSWER' || $CALLSTATUS eq 'ANSWERED') ) || ($CALLSTATUS eq 'CONGESTION'))
  {
      $AGI->stream_file('nbdy-avail-to-take-call'); #disconnected
      																	#$AGI->stream_file('agent-loggedoff');
      sleep(1);
      $AGI->stream_file('call-terminated');
  }
}

$CALLSTATUS 	= $AGI->get_variable(DIALSTATUS);

if ($CALLSTATUS eq 'ANSWER' || $CALLSTATUS eq 'ANSWERED')
{
	 $answeredtime = $AGI->get_variable(ANSWEREDTIME);
		
	 if(!$is_sip )
	 {
	 			CutBalance($OrderId,$callrate,$answeredtime);
	 		  #my $priority=4;$res =$AGI->set_priority($priority);
	 }
	 
}

my $t = $AGI->exec("StopMonitor $C");
$AGI->hangup();
sleep(3);
system("sox $d_path/$wav_file -r 8000 $d_path/$gsm_file resample -ql");

############# Call Recording Information Goin Into Database       #########
			
			$strQry="select max(serialno) from callrecord";
			my @ResultSet	= Db->ExecuteQuery($strQry);
						$serialno = $ResultSet[1][0];
			
			if($serialno eq '') {
				
				$strQry="insert into callrecord(serialno) values(0)";
				
			}
			
			myVerbose("Aarfeen: $CalledNumber");
			
			$serialno = $serialno + 1;
			$strQry="insert into callrecord values($serialno, \"$calleridnum\",\"$tempCalledNumber\",\"$tempFinalDate\",\"$d_path/$wav_file\", \"$tempFinalDate\")";
			my @ResultSet	= Db->ExecuteQuery($strQry);
			
			##################################################################
			
exit;


sub OUTPUT
{
	my ($lable,$value) =@_;
	
	$g_OUTPUT .="($lable=$value)-"
}
#	OUTPUT("\$ChannalName",$ChannalName);	
#	OUTPUT("\$lineno",$lineno);
#	$AGI->verbose("$g_OUTPUT\n",3);

sub billing_for_other_calls
{

	($OrderId,$callrate) = setup_billing($calleridnum);

	if ( $OrderId eq '-1')
	{
			#No Talk time balance in ur account
			$AGI->stream_file('not-enough-credit'); #disconnected
			$AGI->hangup();
			exit;
	}
	
}

# OUT = 1 for sip and 0 for Zap
sub allowCallForwarding
{
			
			if ( $CALLSTATUS eq 'BUSY' )
			{
						if ($CALLSTATUS eq 'BUSY' && ( $g_DATA{MINEXT} <= $g_DATA{EXTBUAY} && $g_DATA{MAXEXT} >= $g_DATA{EXTBUAY} ) )
						{
							#its mean sip dialstr
							$dialstr = "SIP/".$g_DATA{EXTBUAY} . "|$dial_up_to_seconds|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
							$res = $AGI->exec("DIAL $dialstr");
							return 1;
						}
						else
						{
							billing_for_other_calls();
							$dialstr = "Zap/" . $lineno . "/" . $Result[1][1] .  $g_DATA{EXTBUAY};	
							$res = $AGI->exec("DIAL $dialstr");
							return 0;
						}
			}
			elsif ($CALLSTATUS eq 'NOANSWER' )
			{
					
						if ($CALLSTATUS eq 'NOANSWER' && ( $g_DATA{MINEXT} <= $g_DATA{EXTANSWER} && $g_DATA{MAXEXT} >= $g_DATA{EXTANSWER} ) )
						{
			
							#its mean sip dialstr
							$dialstr = "SIP/".$g_DATA{EXTANSWER} . "|$dial_up_to_seconds|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
							$res = $AGI->exec("DIAL $dialstr");
							return 1;
						}
						else
						{
							billing_for_other_calls();
							$dialstr = "Zap/" . $lineno . "/" . $Result[1][1] .  $g_DATA{EXTANSWER};	
							$res = $AGI->exec("DIAL $dialstr");
							return 0;
						}
			}
			elsif ($CALLSTATUS eq 'CHANUNAVAIL')
			{		
					
					if ($CALLSTATUS eq 'CHANUNAVAIL' && ( $g_DATA{MINEXT} <= $g_DATA{EXTLOG} && $g_DATA{MAXEXT} >= $g_DATA{EXTLOG} ) )
					{
							#its mean sip dialstr
							$dialstr = "SIP/".$g_DATA{EXTLOG} . "|$dial_up_to_seconds|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
							$res = $AGI->exec("DIAL $dialstr");
							return 1;
					}
					else
					{
						billing_for_other_calls();
						$dialstr = "Zap/" . $lineno . "/" . $Result[1][1] .  $g_DATA{EXTLOG};	
						$res = $AGI->exec("DIAL $dialstr");
						return 0;
					}
			}
}

sub myVerbose
{
	my ($pStr)=@_;
	
	return 0;
	$pStr =~ s/\n/ /ige;
	
	$AGI->verbose("$pStr\n", 3);

}


sub callrecording
{
		my ($phoneno) =@_;
		my $CalledNumber = $phoneno;
		my $CurDate;
		$d_path	 = "/var/www/html/recordings";
		
		$callstart= currentDbDate();	
		$CurDate = $AGI->get_variable("DATETIME");
		$CurDate =~ s/://gsi;
		$CurDate=substr($CurDate,4,4) . substr($CurDate,2,2) .substr($CurDate,0,2) .substr($CurDate,8,7);
		
		$tempsql ="select curtime()";
		@tempResult	= Db->ExecuteQuery($tempsql);
		$tempResult[1][0];					
		$tempFinalDate = "$callstart $tempResult[1][0]";
		$tempCalledNumber = $CalledNumber;
			
			
			
		
		
		$endofLoop=1;
while($endofLoop==1) {	
			
			$random = int( rand(60000));
		
		$gsm_file = "GSM$random-FILE.gsm";
		$wav_file = "WAV$random-FILE.WAV";
		
		
		$strQry = "select * from callrecord where filepath=\"$d_path/$wav_file\" ";
		my @ResultSet	= Db->ExecuteQuery($strQry);
				
						if($Result[1][0] ne '') {
							
							
							
							$endofLoop=1;
														
							}
					
						else {
							
						$endofLoop=0;
						
		
						
						}
							
			}
		
		
		
			$res = $AGI->exec("Monitor WAV|$d_path/WAV$random-FILE|m");
			#system("sox $d_path/$wav_file -r 8000 $d_path/$gsm_file resample -ql");
} 
 
sub currentDbDate
{
	
		my $strSQL	= "
				select curdate()

					";
					
	my @Result	= Db->ExecuteQuery($strSQL);
	return $Result[1][0];
}

sub setup_billing
{
	my ( $Exten ) =@_;

		my @Result	= Db->ExecuteQuery("select id,talktime from buddies_relation where name='$Exten'");
		my $Cents		= $Result[1][1];
		$g_Cents    = $Result[1][1];
		
		if($Cents<=0)
		{
			# sorry u dont have an enough talk time in ur account
			$Cents=0;
			return ('-1','-1');
		}

		my $bal=$Cents/100;
		my $DollarBal			=sprintf("%d",$bal);
		my $CentsBal			=sprintf("%d",(sprintf("%d",$bal*100)%100));
		my $Totalcents 		=$DollarBal*100 +  $CentsBal;
		
		my %Hash;
		
		$Hash{Rates} =0.052;
		
		my $totalCents	=$Totalcents ;
		my $callrate		=sprintf("%d",$Hash{Rates}*100);
		my $totalMinutes=sprintf("%d",$totalCents/$callrate);                   
		my $totalSeconds=sprintf("%d",((($totalCents%$callrate)/$callrate)*60));
		
		
	#$callrate=$callrate/100;		
	#my $min=sprintf("%d",$answeredtime/60);
	#my $Sec=sprintf("%d",$answeredtime%60);
	#if($Sec>0)
	#{
	#	$min++;
	#}		
	#		
	#	$Cut=	$min*$callrate;
	#	
	#	$Cost=$Hash{broadvoice} * $min;
	#	
	#	$profit=$Cut-$Cost;
	#	
	#	if($dialstatus ne "ANSWER") {$profit=0;}
	return ($Result[1][0],$callrate);
}

sub CutBalance
{
	
		my ($id,$Rate,$CallSec) = @_;
		my $min=sprintf("%d",$CallSec/60);
		my $Sec=sprintf("%d",$CallSec%60);		
		if($Sec>0)
		{
		$min++;
		}
		
		my $Cut=	$min*$Rate;
		
		
		#$AGI->verbose("$extention = ($id) min($min),sec($Sec),cut($Cut)",3);
			
		my $amount = $g_Cents - $Cut;
		
		
		
		my $strSQL	= "Update buddies_relation set talktime =\"$amount\" where id=\"$id\" ";
			
		Db->ExecuteQuery($strSQL);
		
		#$AGI->verbose("min($min),sec($Sec),cut($Cut),amount($amount),qury($strSQL)",3);
}


sub readRecordinSize {
	
my $totalSize;

my $recordingsPath = "/var/www/html/recordings/";
	
	
	 opendir(DIR, $recordingsPath) || die "can't opendir $DOCSPATH: $!";

                @dots = readdir(DIR);

                foreach $eDIR (@dots)
                {

									 my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($recordingsPath.$eDIR);
									 
									 			if($eDIR ne '.' && $eDIR ne '..') {
									 				
									 				$totalSize = $totalSize + $size;
									 
									 														 					
									 				}
									 				
									 
									}

                
                $totalSize = ($totalSize / 1024) / 1024;   # Converting Bytes into Megabytes
                $fileSize  = sprintf("%.2f", $totalSize);  #Rounding to 2 Digits after Decimal
                
         return $fileSize;         
                  

	
	}


Article Reviews

Write a Review

Your email address will not be published. Required fields are marked *

Required Field. Minimum 5 characters.

Required Field. Minimum 5 characters, maximum 50.

Required field.There is an error with this field.

Required Field.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

There are no reviews for this article. Be the first one to write a review.
Get 3CX - Absolutely Free!
Link up your team and customers Phone System Live Chat Video Conferencing

Hosted or Self-managed. Up to 10 users free forever. No credit card. Try risk free.

3CX
A 3CX Account with that email already exists. You will be redirected to the Customer Portal to sign in or reset your password if you've forgotten it.