понедельник, 4 апреля 2011 г.

Callback на Asterisk с базой callback-номеров в SQL

Однажды нашей компании понадобился коллбэк. Недолго думая, была выведена наиболее оптимальная схема: AGI-скрипт, который каждый входящий CallerID проверяет по базе, и если есть вхождения, перезванивает, соединяя с IVR.

Получился следующий скрипт:
#!/usr/bin/perl -w
use strict;
use DBI;
use Asterisk::AGI;

my $mysqlserver='127.0.0.1'; # сервер MySQL
my $mysqlbase='asterisk'; # база MySQL
my $mysqlport='3306'; # порт MySQL
my $mysqluser='user'; # Пользователь MySQL
my $mysqlpassword='password'; # Пароль MySQL
my $mysqltable='callback'; # таблица с номерами коллбэка
my $numberrow="number"; # столбец с номерами коллбэка
my $outcontext="out"; # контекст, в котором можно набирать исходящие
my $incontext="in"; # контекст, с которым соединяем исходящие вызовы коллбэка (IVR например)
my $inexten="s"; # добавочный, с которым соединяем исходящие вызовы
my $inprio"1"; # приоритет добавочного



my $callfile="/var/spool/asterisk/outgoing/callback".time().".call";

my $dbh=DBI->connect("DBI:mysql:database=$mysqlbase;host=$mysqlserver;port=$mysqlport",$mysqluser,$mysqlpassword)
or die "Can\'t connect to MySQL Server!\n";

sub check_number {
    my $query=$dbh->prepare("select $numberrow from $mysqltable where $numberrow = \"$_[0]\"");
    $query->execute();
    my $queryresult=$query->fetchrow();
    $query->finish();
    return $queryresult;
}

my $agi = new Asterisk::AGI;

my %input = $agi->ReadParse();

if (check_number($input{"callerid"})) {
    open(CF,'>',$callfile) or die "Can\'t create callfile!";
    print(CF    "Channel: Local\/".$input{"callerid"}."\@".$outcontext."\n".
                "MaxRetries: 3\n".
                "RetryTime: 4\n".
                "WaitTime: 30\n".
                "Context: ".$incontext."\n".
                "Extension: ".$inexten."\n".
                "Priority: ".$inprio."\n".
                "Callerid: ".$input{"callerid"}."\n"
          );
    close(CF);
    $dbh->disconnect();
    $agi->hangup();
}

$dbh->disconnect();
Сам код во входящем контексте Астериска выглядит просто:
exten => s,1,NoOp
exten => s,n,AGI(callback.pl)
exnte => s,n,Background(myivr)  ;;;; Дальнейшая обработка звонка (если не прошел проверку на коллбэк)

Привязки к типам данных в ячейках таблицы MySQL нет, главное, чтобы она выглядела как-то так:

+----+--------------+---------------------+
| id | number       | description         |
+----+--------------+---------------------+
| 10 | 89261234567  | User1               |
| 13 | 89262345767  | User2               |
|  3 | 380931352345 | User3               |
| 14 | 380953445434 | User4               |
+----+--------------+---------------------+

Вот, собственно, и все.

Комментариев нет: