Понадобилось в одном офисе поднять факс сервер на Asterisk с возможность принимать на e-mail, а также отправлять с e-mail. Честно говоря, не нравится мне тема факсов в VoIP. Но это из раздела «Вы не любите кошек…?»

Поднимать буду на CentOS-6, Asterisk-1.8.  Отправка и прием факсов с помощью SpanDSP.  Первым делом поставим нужные пакеты.

yum install -y gcc  ghostscript sharutils glibc-headers glibc-devel kernel-headers autoconf zlib-devel gcc-c++ libjpeg-devel mgetty-voice libtiff-devel spandsp spandsp-devel

После этого нужно заново собрать Asterisk, указав галочку напротив SpanDSP.  Проверить собран Астериск с поддержкой SpanDSP можно командами

core show application SendFAX
core show application ReceiveFAX

Прием факсов в Астериск происходит следующим образом.  При обнаружении в канале тон факса, Астериск запускает в том же контексте экстен с именем «fax», где и происходит прием факса, с последующей оправкой на почту.

Пример диалплана для приема Факсов

[incoming]

exten => fax,1,NoOp(-------------------Call from ${CALLERID(number)} to ${EXTEN}------------------)
exten => fax,n,Goto(fax-rx,receive,1)

[fax-rx]

exten => receive,1,NoOP(------------------- FAX from ${CALLERID(number)} ------------------)
exten => receive,n,Answer()
exten => receive,n,Set(FILENAME=fax-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)}-${CALLERID(number)})
exten => receive,n,Set(FAXFILE=/var/spool/asterisk/fax/receive/${FILENAME}.tif)
exten => receive,n,Set(FAXOPT(headerinfo)=Received by ${CALLERID(number)} ${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M)})
exten => receive,n,Set(FAXOPT(localstationid)=OFFICE)
exten => receive,n,Set(FAXOPT(maxrate)=14400)
exten => receive,n,Set(FAXOPT(minrate)=2400)
exten => receive,n,NoOp(FAXOPT(ecm) : ${FAXOPT(ecm)})
exten => receive,n,NoOp(FAXOPT(headerinfo) : ${FAXOPT(headerinfo)})
exten => receive,n,NoOp(FAXOPT(localstationid) : ${FAXOPT(localstationid)})
exten => receive,n,NoOp(FAXOPT(maxrate) : ${FAXOPT(maxrate)})
exten => receive,n,NoOp(FAXOPT(minrate) : ${FAXOPT(minrate)})
exten => receive,n,NoOp(**** RECEIVING FAX : ${FAXFILE} ****)
exten => receive,n,ReceiveFAX(${FAXFILE})
exten => receive,n,Hangup()

exten => h,1,NoOP(------------------- FAX from ${CALLERID(number)} ------------------)
exten => h,n,NoOP(------------------- STATUS ${FAXSTATUS} ${FAXERROR} ------------------)
exten => h,n,system(/var/lib/asterisk/agi-bin/fax/fax-process.pl --to fax@asterisk.org --from asterisk@asterisk.org --subject "Fax prineat s ${URIENCODE(${CALLERID(number)})} ${URIENCODE(${CALLERID(name)})}" --attachment ${FILENAME}.pdf --type application/pdf --file ${FAXFILE});

Скрипт для конвертации полученного факса и отправки на почту находиться по этой ссылке fax-process.

Далее,  для отправки факса, нужно положить в любую папочку на сервере факс в формате tif и дать команду на отправку, с помощью call файлов.

[fax-tx]

exten => send,1,NoOP(------------------- FAX from ${CALLERID(number)} ------------------)
;exten => send,n,Set(FAXOPT(ecm)=yes)
exten => send,n,Set(FAXOPT(headerinfo)=Fax from OFFICE)
exten => send,n,Set(FAXOPT(localstationid)=OFFICE)
exten => send,n,Set(FAXOPT(maxrate)=14400)
exten => send,n,Set(FAXOPT(minrate)=2400)

exten => send,n,WaitForSilence(500,1,15)
exten => send,n,NoOP(--- ${WAITSTATUS}  ---)
exten => send,n,Answer()
exten => send,n,Wait(3)
exten => send,n,SendFAX(${PICTURE})
exten => send,n,NoOP(--- ${FAXSTATUS} ---${FAXERROR} ---${REMOTESTATIONID} ---)
exten => send,n,Hangup()

exten => h,1,NoOP(------------------- FAX to ${EXTEN} with ${FAXSTATUS} -----------------)
exten => h,n,GotoIf($["${FAXSTATUS}" = "SUCCESS"]?h,success:h,failed)
exten => h,n(failed),Hangup()
exten => h,n(success),system(/var/lib/asterisk/agi-bin/fax/sendfax_success.pl ${PICTURE})
exten => h,n,Hangup()

Далее Перловый скрипт, который создает call-файл.

#!/usr/bin/perl

use strict;
use warnings;

my $work_dir            = "/var/spool/asterisk/monitor/fax";
my $outgoing_dir        = "/var/spool/asterisk/outgoing";
my $context_to          = "outgoing_call";
my $send_to             = "680090";
my $call_file           = "Fax_$send_to";
my $tif                 = "NameFileInTifFormat.tif";

open(FILE,">$work_dir/tmp/$call_file")  or die "Cannot write file: $!\n";

print FILE "Channel: Local/$send_to\@$context_to\n";
print FILE "Context: fax-tx\n";
print FILE "Extension: send\n";
print FILE "MaxRetries: 2\n";
print FILE "RetryTime: 600\n";
print FILE "WaitTime: 25\n";
print FILE "Set: PICTURE=$work_dir/queue/$tif\n";

close(FILE);

sleep(1);
system("/bin/mv $work_dir/tmp/$call_file $outgoing_dir");

После отправки факса запускается перловый скрипт «sendfax_success.pl», который отправляет на почту информацию о статусе отправки, и перемещает отправленные файлы в другую директорию. В принципе сам скрипт как пример(выставляю по просьбе трудящихся), можете переделать под ваши задачи.

#!/usr/bin/perl
#
#
#
#       Developed by 2012 Mihail Belobrov
#
#       Скрипт подтверждения успешной отправки факса
#

use strict;
use warnings;
use Net::SMTP;

my $response = $ARGV[0];
my $done_dir = "/var/spool/asterisk/fax/send/done";
my $queue_dir = "/var/spool/asterisk/fax/send/queue";
my $from_mail;

#парсим нужные данные
chomp($response);
my $filename =          $1 if ($response =~ /\/var\/spool\/asterisk\/fax.+(sendto.+\.tif)/);
my $phone =             $1 if ($response =~ /\/var\/spool\/asterisk\/fax.+sendto_(\d+)_.+\.tif/);
my $faxname =           $1 if ($response =~ /\/var\/spool\/asterisk\/fax.+sendto_\d+_(.+\.tif)/);
my $file_without =      $1 if ($response =~ /\/var\/spool\/asterisk\/fax.+(sendto_\d+_.+)\.tif/);

sleep(3);
#Перемещаем успешно, переданные факсы в папку done
system("/bin/mv $response $done_dir");

#Выбираем дополнительные данные

my $mail_user_to = 'fax1\@yourdomain.com';
my $mail_user_from = 'asterisk\@yuordomain.com';
my $mail_server = 'mail.yourdomain.com';
my $mail_user = 'fax1\@yourdomain.com';

my $subj = 'Fax otrpavlen';
my $Body='Факс '.$faxname.' на номер '.$phone.' отправлен успешно!';

my $smtp = Net::SMTP->new($mail_server);
$smtp->mail($ENV{USER});
$smtp->to($mail_user);
$smtp->data();
$smtp->datasend("To: $mail_user_to\n");
$smtp->datasend("From: $mail_user_from\n");
$smtp->datasend("Subject: $subj\n");
$smtp->datasend("\n");
$smtp->datasend("$Body\n");
$smtp->dataend();
$smtp->quit;
Конвертировать tif из pdf можно командой
/usr/bin/gs -q -dNOPAUSE -dBATCH -sDEVICE=tiffg4 -sOutputFile=Fax.tif Fax.pdf

Положить факс-pdf можно вручную, а можно скинуть через FTP или Samba или через почту. Подбирайте наиболее подходящий для вас вариант, экспериментируйте.