Upgrade 3CX to v18 and get it hosted free!

PERL-ZAPSIPIAX_INCOMMING_OUTGOING-AGI

Author image

// Version 1 (c) for ZAP incomming call file name zapincomming.agi by imran ( Pakistan )
// features in this agi are handled:

// (1) Call Recording enbabled / disabled database driven controle.
// (2) Call forwarding enbabled / disabled database driven controle.
// (3) Voice Mail enbabled / disabled database driven controle.
// (4) Call Billing Customized CDR database driven controle ( Needs to specify your own call rates )
// (5) Auto IVR response Specify IVR message or specify Extension(s) or Input your Number for direct dial database driven controle.
// (6) IAX/SIP/ZAP dialing You can make SIP/IAX call or local call through zap channel on your PSTN ternmial.
// (7) Call Debuggin you can view call logs via writing filing rather than using verbose expensive function.

// Pending features have to be done( Currently Working on these features ):
// (1) Call Blocking.
// (2) Charge your Card / Account via IVR. ( You can charge your talk time, cardCharging feature)
// (3) Pay your bill through free phone call. ( Through Credit Card charging )
// (4) Sending Simple Messages. (SMS) ( you can send your limited message )
// (5) Sending an image. ( movie ) ( You can send your live movie to the remote side )
// (6) Sending fax copy. ( You can send your document as a fax )
// (7) send email when you are not logon. ( You can send email message to the customer’s device if you are not log on )


#!/usr/bin/perl
use Asterisk::AGI;
my $ModuelPath  = "/var/www/cgi-bin/modules";
use lib "/var/www/cgi-bin/modules";
use Db;

$AGI = new Asterisk::AGI;

$AGI->answer();

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


my $dial_up_to_seconds=30;
my $dialstr;
my $DialedNo;
my $d_path	 	= "/var/www/html/recordings";
my $ivrPath 		= "/var/www/html/ivrSounds";
my $gsm_file;
my $wav_file;
my %g_DATA;
my $ChannalName="";
my $isExt;
my $info;
my $CALLSTATUS;


my $g_OUTPUT	="\n[ START ]\n";
my $DEBUG_OUTPUT_FLAG 	=1;

$CDR_HASH{CALLERID}	 		='';
$CDR_HASH{CALLRECORDINGFILE} 	='';      
$CDR_HASH{CONTEXT} 			=$AGI->get_variable("CONTEXT");
$CDR_HASH{BILLSEC}			=0;
$CDR_HASH{USERFIELD}		='';
$CDR_HASH{CLID} 			='';
$CDR_HASH{AMAFLAGS} 		=3;	
$CDR_HASH{APPDATA}			="";


$CDR_HASH{BILLSEC}=0;


if ( $calleridnum eq '' )
{
	$calleridnum ='unknown';
	$CDR_HASH{CALLERID} =$calleridnum;
}

$CDR_HASH{CALLERID} =$calleridnum;

$ChannalName 		= $AGI->get_variable("CHANNEL");
#$ChannalName : Zap/1-1

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

my $lineno =$1;

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

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

if($Result[1][0] eq "")
{	
	$AGI->stream_file("$ivrPath/welcomt2ippx","0123456789");	
	sleep(3);
	exit;
}

$isExt	=$Result[1][0];
$info	=$Result[1][1];

#when Extension are defined
if($isExt)
{
	# in $info= "100023-100024" out $info= "100023&SIP/100024&SIP/"
	my @DATA = split (/-/,$info);
	for ( my $nIndex=0; $nIndex <$#DATA; $nIndex++ )
	{
		if (  $DATA[$nIndex] ne '' )
		{
			$DialedNo = 	$DATA[$nIndex];
			last;
		}
	}
	if ( $DialedNo  eq '' )
	{
		# extension is not defined
		sleep(3);
		exit;
	}
	
	%g_DATA=getAccessOfCalledExten($DialedNo);
	
	$info =~ s/\-/&SIP\//g; 
	$dialstr = "SIP/$info|$dial_up_to_seconds|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
	
}

else
{
	my $strSQL	= "
	select 0map,1map ,2map ,3map ,path from ivr where id='$info'";

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

	if($Result[1][4] eq "")
	{
		$AGI->stream_file("$ivrPath/welcomt2ippx","0123456789");	
		sleep(3);
		exit;
	}	

	$n0map	=$Result[1][0];
	$n1map	=$Result[1][1];
	$n2map	=$Result[1][2];
	$n3map 	=$Result[1][3];
	$path	=$Result[1][4];
	
	# in = $path ="woman.gsm" out = $path = "woman";
	$path =~ s/\..*$//g;
		
	for($i=0;$i<3;$i++)
	{
		$DialedNo="";
		$DialedNo= $AGI->get_data("$ivrPath/$path", 5000, 3);
		
		if($DialedNo eq "")
		{
			if($i == 2){$DialedNo=$n0map;}
			else	{next;}
		}
		elsif( $DialedNo ==0 )
		{
			$DialedNo=$n0map;
		}
		elsif($DialedNo ==1)
		{
			$DialedNo=$n1map;
		}
		elsif($DialedNo ==2)
		{
			$DialedNo=$n2map;
		}
		elsif($DialedNo ==3)
		{
			$DialedNo=$n3map;
		}
		else
		{
			if(!(length($DialedNo)==3))
			{
				next;
			}
		}
		
		%g_DATA=getAccessOfCalledExten($DialedNo);
		$dialstr = "SIP/".$DialedNo . "|$dial_up_to_seconds|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
		last;
											
	}			
}


if( $g_DATA{MINEXT} <= $DialedNo && $g_DATA{MAXEXT} >= $DialedNo )
{
		#valid Extension
		$AGI->stream_file("pls-wait-connect-call");
}
else
{
	 #Sorry Invalid Extension
	 $AGI->stream_file('you-dialed-wrong-number');
	 $AGI->hangup();
	 exit;
}
			 
	 if ( $g_DATA{CALLRECORDING} eq 'Y' )
	 {
	 	callrecording($DialedNo);
	 }
		
	 $res = $AGI->exec("DIAL $dialstr");
	 
	 $CALLSTATUS = $AGI->get_variable(DIALSTATUS);
	 
	 	$CDR_HASH{CHANNEL}	 =$AGI->get_variable("CHANNEL");
		$CDR_HASH{CALLEDID}	 =$DialedNo;
		$CDR_HASH{DIALSTATUS}=$CALLSTATUS;
		$CDR_HASH{ANSWERTIME}=$answeredtime;
		$CDR_HASH{APPDATA}	 =$dialstr;
		

	  if ( $CALLSTATUS ne 'ANSWER' && $CALLSTATUS ne 'ANSWERED')
	  {
	      
	      if ( $g_DATA{CALLFORWARDING} eq 'Y' )
	      {
	      
	      	$dialstr = &callforwording();
	 		
	 		if( $dialstr eq '' )
	 		{
	 			goto LABLE2;
	 		}
	 		$res = $AGI->exec("DIAL $dialstr");     	
	      	$CALLSTATUS = $AGI->get_variable(DIALSTATUS);
	      	
	      	$CDR_HASH{CHANNEL}	 =$AGI->get_variable("CHANNEL");
			$CDR_HASH{CALLEDID}	 =$DialedNo;
			$CDR_HASH{DIALSTATUS}=$CALLSTATUS;
			$CDR_HASH{ANSWERTIME}=$answeredtime;
			$CDR_HASH{APPDATA}	 =$dialstr;
	      	
	      	if ( $CALLSTATUS eq 'ANSWER' or $CALLSTATUS eq 'ANSWERED')
	      	{
	      		goto LABLE;
	      	}
	      }
	      
	      LABLE2:
	      
	      if ( $g_DATA{VOICEMAIL} eq 'Y' )
	      {
	  		$res = $AGI->exec("VoiceMail u$DialedNo");	
			sleep(2);
			system("chmod +777 /var/spool/asterisk/voicemail/default/$phoneno/ -R");    
	      }
	      else
	      {
		      $AGI->stream_file('nbdy-avail-to-take-call'); #disconnected  #$AGI->stream_file('agent-loggedoff');
		      sleep(1);
		      $AGI->stream_file('call-terminated');
		      sleep(1);
		      $AGI->stream_file('thanks-for-using');
	      }
	  }
  
  LABLE:
	
	if ( $CALLSTATUS eq 'ANSWER' or $CALLSTATUS eq 'ANSWERED')
	{
		$CDR_HASH{BILLSEC}		=$CDR_HASH{ANSWERTIME} - 3;
	} 
	
	if ( $g_DATA{CALLRECORDING} eq 'Y' )
	{
		my $C = $AGI->get_variable(CHANNEL);
		my $t = $AGI->exec("StopMonitor $C");
		$AGI->hangup();
		sleep(3);
		system("sox $d_path/$wav_file -r 8000 $d_path/$gsm_file resample -ql");
	}
	else
	{
		$AGI->hangup();
	}


&saveCdrData(%CDR_HASH);

exit;
	 

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

	return;
}

sub callrecording
{
	my ($phoneno) =@_;
	my $CalledNumber = $phoneno;
	my $CurDate;
	
	$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);
	$gsm_file = "Callfrom-$calleridnum-CallTo-$CalledNumber-at-$CurDate.gsm";
	$wav_file = "Callfrom-$calleridnum-CallTo-$CalledNumber-at-$CurDate.WAV";
	$res = $AGI->exec("Monitor WAV|$d_path/Callfrom-$calleridnum-CallTo-$CalledNumber-at-$CurDate|m");
	
	$CDR_HASH{CALLRECORDINGFILE} = $gsm_file;
} 

sub getAccessOfCalledExten
{
	my ( $ext )=@_;
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,
				calltype
				 
				from buddies_relation
				where name=\"$ext\"
				";
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{CALLTYPE}	   = $Result[ 1][ 14];

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];

return %g_DATA;

}


// NOTE: this function needs your customiezed call forwading functionality depends on call status BUSY, NOANSWER, NOAVAILABLE etc
 sub callforwording
{
	my $dial="";
	
	if ( $CALLSTATUS eq 'BUSY' )
	{
		if ( $g_DATA{MINEXT} <= $g_DATA{EXTBUAY} && $g_DATA{MAXEXT} >= $g_DATA{EXTBUAY} ) 
		{
			# make here SIP/IAX/ZAP dailstring according to the dype of $g_DATA{EXTBUAY} number
			
			if( $g_DATA{CALLTYPE} eq '1' )
			{
				$dial = = "SIP/" . $g_DATA{EXTBUAY} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
			}
			
			else if( $g_DATA{CALLTYPE} eq '2' )
			{
				$dial = = "IAX2/admin:admin123\@carrier/".$g_DATA{EXTBUAY} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
			}
			
			else if( $g_DATA{CALLTYPE} eq '3' )
			{
				$dial = = "ZAP/g1/" . $g_DATA{EXTBUAY} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
			}
			
			$DialedNo =$g_DATA{EXTBUAY};
		
			return $dial;
		}
			  
		return $dial;	
	}
	
	
	if ( $CALLSTATUS eq 'NO ANSWER' )
	{
		if ( $g_DATA{MINEXT} <= $g_DATA{EXTANSWER} && $g_DATA{MAXEXT} >= $g_DATA{EXTANSWER} ) 
		{
			# make here SIP/IAX/ZAP dailstring according to the dype of $g_DATA{EXTANSWER} number
			
			if( $g_DATA{CALLTYPE} eq '1' )
			{
				$dial = = "SIP/" . $g_DATA{EXTANSWER} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
			}
			
			else if( $g_DATA{CALLTYPE} eq '2' )
			{
				$dial = = "IAX2/admin:admin123\@carrier/" . $g_DATA{EXTANSWER} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
			}
			
			else if( $g_DATA{CALLTYPE} eq '3' )
			{
				$dial = = "ZAP/g1/" . $g_DATA{EXTANSWER} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
			}
			$DialedNo =$g_DATA{EXTANSWER};
			return $dial;
		}
		
		return $dial;	
	}
	
	if ( $CALLSTATUS eq 'NOAVAILABLE' )
	{
		if ( $g_DATA{MINEXT} <= $g_DATA{EXTLOG} && $g_DATA{MAXEXT} >= $g_DATA{EXTLOG} ) 
		{
			# make here SIP/IAX/ZAP dailstring according to the dype of $g_DATA{EXTLOG} number

			if( $g_DATA{CALLTYPE} eq '1' )
			{
				$dial = = "SIP/" . $g_DATA{EXTLOG} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
			}
			
			else if(  $g_DATA{CALLTYPE} eq '2' )
			{
				$dial = = "IAX2/admin:admin123\@carrier/" . $g_DATA{EXTLOG} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
			}
			
			else if(  $g_DATA{CALLTYPE} eq '3' )
			{
				$dial = = "ZAP/g1/" . $g_DATA{EXTLOG} . "|20|HL(" . (100 * 60 * 1000) . ":60000:30000)|tr";
			}
			$DialedNo =$g_DATA{EXTLOG};
			return $dial;
		}			
		
		return $dial;	
	}
	
	return $dial;
}

sub savelog 
{
	open(FILE, ">>/var/lib/asterisk/agi-bin/dialoutlog.txt") or die("Couldn't open dialoutlog.txt\n");
	
	print FILE "(". localtime() .")".$g_OUTPUT;
	
	close(FILE);
}

# table mycdr by imran
# IN Hash
# OUT nothing
sub saveCdrData
{ 
	my (%HASH)=@_;
	   	 
	Db->ExecuteQuery("insert into mycdr(clid,src,dst,dcontext,channel,duration,billsec,disposition,calldate,recordedfile,amaflags,userfield,lastdata)
	values('$HASH{CLID}','$HASH{CALLERID}','$HASH{CALLEDID}','$HASH{CONTEXT}','$HASH{CHANNEL}','$HASH{ANSWERTIME}','$HASH{BILLSEC}','$HASH{DIALSTATUS}',sysdate(),'$HASH{CALLRECORDINGFILE}','$HASH{AMAFLAGS}','$HASH{USERFIELD}','$HASH{APPDATA}')");
	
	if($DEBUG_OUTPUT_FLAG)
	{
		$g_OUTPUT	.="[ END ]\n\n";
		#$AGI->verbose("$g_OUTPUT", 3) ;
		&savelog();
	}
}


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.