Cuando salga esta nota, yo estaré impartinedo una conferencia en Campus Party 2010 sobre marcación automática usando Asterisk.
Hice un pequeño programa en perl llamado “joder.pl” que hace exactamente lo que su nombre dice.
Pones un número a marcar y el lapso en segundos y marca a un teléfono victima y repite esto hasta que interrumpes el programa.
Es una versión muy simplificada de un marcador, pero es para mostrar las posibilidades infinitas para crear programas interesantes…
Antes que nada es necesario tener una instalación de Asterisk operando y con lo siguiente en sus archivos de configuración:
en el archivo /etc/asterisk/manager.conf deben de tener algo así:
[general]
displaysystemname = yes
enabled = yes
;webenabled = yes
port = 5038
bindaddr = 0.0.0.0
[test]
secret = test
writetimeout = 100000
read = system,call,log,verbose,command,agent,user
write = system,call,log,verbose,command,agent,user
En el archivo de dialplan de Asterisk conocido como /etc/asterisk/extensions.conf debera estar algo así:
[dial]
exten => 666,1,Playback(tt-monkeys)
exten => 666,n,hangup
Al invocar el programa así:
./joder.pl 56581111 30
El programa marca a la Profeco y cada 30 segundos hace lo mismo, al contestar toca un audio de “changos”, hasta que interrumpimos el programa con un control+C.
En este caso estamos usando un API de Asterisk conocidop como AMI (Asterisk Manager Interface).
El programa se deja para fines didácticos y no nos hacemos responsables de su uso, y menos del gasto telefónico que esto genere.
#!/usr/bin/perl
#====================================================================#
# Program => joder.pl (In Perl 5.x) #
#====================================================================#
# Autor => Fernando "El Pop" Romo (pop@cofradia.org) #
# Creation date => 10/Aug/2010 #
#--------------------------------------------------------------------#
# Info => This program is a litle demostration of automatic dialing. #
# take the phone argument and make a lot of disturbing #
# calls. #
#--------------------------------------------------------------------#
# (c) 2010 - Fernando Romo / Incuvox #
#--------------------------------------------------------------------#
# This code are released under the GPL License. Any change must be #
# report to the authors #
#====================================================================#
# Load Modules
use strict;
use POSIX;
use IO::Socket;
use Socket;
use Fcntl;
# signal traps
$SIG{PIPE} = 'IGNORE';
$SIG{INT} = $SIG{TERM} = $SIG{HUP} = 'Terminate';
# Number to dial
my $Number_To_Dial = $ARGV[0];
my $Delay = $ARGV[1];
# Socket handler for Asterisk
my $asterisk_handler;
# Flags to connect to Asterisk
my $manager_connect_flag = 1;
#--------------------------------------------------------------------
# [Pop] Developer Note: The Sys_Parms() load the necesary values from
# the Parameter table in the DB. I left this values comment for test
# and documentation purposes.
#--------------------------------------------------------------------
my %Parm = ();
# Dial parametrs
$Parm{dialer}{timeout} = 30000; # Dial Timeout
$Parm{dialer}{absolute_timeout} = 180; # absolute max time of a call in seconds, 0 = no limit
$Parm{dialer}{caller_id} = "5556581111"; # Caller_ID to report to carrier (for SIP trunking)
# Asterisk manager parameters
$Parm{asterisk}{host} = "127.0.0.1"; # IP address of * Server
$Parm{asterisk}{port} = 5038; # * manager port
$Parm{asterisk}{user} = "test"; # * Manager user
$Parm{asterisk}{pass} = "test"; # * Manager password
$Parm{asterisk}{events} = 1; # Flag to request event log to * manager
$Parm{asterisk}{trunk} = "Zap/g1"; # Outgoing calls resource
$Parm{asterisk}{context} = "dial"; # Context of the dial
$Parm{asterisk}{exten} = "666"; # Context of the dial
#--------------------------------------------------------------------
#---------------------------------------------------------#
# Function: Terminate() #
#---------------------------------------------------------#
# Objetive: catch the {INT} signal and close connection #
# to sockets and terminate program. #
# Params: none #
# Usage: #
# $SIG{INT} = 'Terminate'; #
#---------------------------------------------------------#
sub Terminate {
close($asterisk_handler); # destroy asterisk manager conection
exit(0); # Exit without error
}
#-----------------------------------------------#
# Function: Nonblock([TCP socket handler]) #
#-----------------------------------------------#
# Objetive: puts socket into nonblocking mode #
# Params: [TCP Socket Handler] #
# Usage: #
# Nonblock($socket); #
#-----------------------------------------------#
sub Nonblock {
my $socket = shift;
my $flags;
$flags = fcntl($socket, F_GETFL, 0)
or die "Can't get flags for socket: $!\n";
fcntl($socket, F_SETFL, $flags | O_NONBLOCK)
or die "Can't make socket nonblocking: $!\n";
}
#-----------------------------------------------#
# Function: Manager_Login #
#-----------------------------------------------#
# Objetive: Send Login Action to Asterisk API #
# Params: none #
# Usage: #
# Manager_Login(); #
#-----------------------------------------------#
sub Manager_Login {
my $command = "Action: Login\r\n";
$command .= "Username: $Parm{asterisk}{user}\r\n";
$command .= "Secret: $Parm{asterisk}{pass}\r\n";
$command .= "Events: ";
if ($Parm{asterisk}{events}) {
$command .= 'on';
}
else {
$command .= 'off';
}
$command .= "\r\n\r\n";
Send_To_Asterisk(\$command);
}
#--------------------------------------------------#
# Function: Connect_To_Asterisk() #
#--------------------------------------------------#
# Objetive: connect program with asterisk manager #
# Params: None #
# Usage: #
# Connect_To_Asterisk(); #
#--------------------------------------------------#
sub Connect_To_Asterisk {
$asterisk_handler = new IO::Socket::INET->new( PeerAddr => $Parm{asterisk}{host},
PeerPort => $Parm{asterisk}{port},
Proto => "tcp",
ReuseAddr => 1,
Type => SOCK_STREAM );
if ($asterisk_handler) {
$asterisk_handler->autoflush(1);
Nonblock($asterisk_handler);
return 0;
}
else {
return 1;
}
}
#--------------------------------------------------------#
# Function: Send_To_Asterisk([message]) #
#--------------------------------------------------------#
# Objetive: Send message to Asterik manager #
# Params: message, socket_handler #
# Usage: #
# Send_To_Asterisk(\$message) #
#--------------------------------------------------------#
sub Send_To_Asterisk {
my $command_ref = shift;
unless ($command_ref eq "" && $manager_connect_flag == 1) {
# if the socket exists send data, if not, turn on reconnection flag
# if (defined(getpeername($asterisk_handler))) {
unless($asterisk_handler eq "") {
my $rv = $asterisk_handler->send($command_ref, 0);
unless (defined $rv) {
# if send fails, turn on reconnection flag
$manager_connect_flag = 1;
}
}
else {
$manager_connect_flag = 1;
}
}
}
#---------------------------------------------------#
# Function: Dial([phone number]) #
#---------------------------------------------------#
# Objetive: originate a phone call via the asterisk #
# #
# Params: phone number #
# Usage: #
# Dial('56581111'); #
#---------------------------------------------------#
sub Dial {
my $Number = shift;
my $command = "Action: Originate\r\n";
$command .= "Channel: $Parm{asterisk}{trunk}/$Number\r\n";
$command .= "Context: $Parm{asterisk}{context}\r\n";
$command .= "Exten: $Parm{asterisk}{exten}\r\n";
$command .= "Priority: 1\r\n";
$command .= "Async: true\r\n";
$command .= "Timeout: $Parm{dialer}{timeout}\r\n";
$command .= "Variable: TIMEOUT(absolute)=$Parm{dialer}{absolute_timeout}\r\n";
$command .= "Callerid: $Parm{dialer}{caller_id}\r\n\r\n";
Send_To_Asterisk(\$command);
}
#======================#
# Main block #
#======================#
if ($Number_To_Dial && $Delay) {
while (1) { # Main loop #
if ($manager_connect_flag) {
$manager_connect_flag = Connect_To_Asterisk();
unless ($manager_connect_flag) {
Manager_Login();
}
}
# Check if the dialer can send calls to asterisk using a semaphore
if ($manager_connect_flag == 0) {
if ($Number_To_Dial) {
Dial($Number_To_Dial);
sleep($Delay);
}
}
} # End of main loop
}
else {
print "Usage => joder.pl [Number to dial] [wait time in seconds]\n";
}
#------------- End of main block ----------
Enjoy!
Saludos… Fernando “El Pop” Romo

Leave a Reply
You must be logged in to post a comment.