Настройка факса (прием) 12.05.2011

В идеале, я бы хотел сделать и прием, и отправку через встроенный факс астериск, но отправка пока вызывает много организационных вопросов (как указывать номер, конвертировать форматы и тд). Здесь я рассмотрю настройку приема факсов.

Самой компанией Digium разработан и продается программный факс для астериск. Его можно скачать и попробовать в бесплатном режиме (с ограничением на одну линию) или докупить линий по 40 долларов, что совсем недорого (по сравнению с обычными факсами).

Попробуем настроить факс в режим, когда принятый факс автоматически отправляется на выбранный нами email.

Установка факса Digium

Сначала скачиваем саму программу. Я воспользовался yum-ом:

yum install asterisk18-res_fax_digium

Дальше покупаем лицензию или получаем бесплатную на одно подключение, запускаем утилиту /usr/sbin/register и регистрируем наш факс.

Создаем файл /etc/asterisk/res_fax.conf (я взял все параметры из исходного примера):

[general]
maxrate=14400
minrate=2400
statusevents=no
modems=v17,v27,v29
ecm=yes

Перезагружаем астериск и проверяем, что модуль факса подгрузился

asterisk*CLI> module show like res_fax
Module                         Description                              Use Count
res_fax.so                     Generic FAX Applications                 1
res_fax_digium.so              Digium G.711 and T.38 FAX Technologies ( 0

а лицензия – подцепилась (я удалил часть строк из вывода)

asterisk*CLI> fax show stats
FAX Statistics:
— --------------
Digium G.711
Licensed Channels    : 1
Max Concurrent       : 0
Digium T.38
Licensed Channels    : 1
Max Concurrent       : 0

Настройка диалплана

В прошлой статье я описал «зародыш» контекста для факса. Пришло время доделать его.

Часть файла я взял из документации к факсу, часть доделал сам. Обращаю ваше внимание, что у астериска должны быть права на запись в папку, которую вы назначаете для приема факсов.

[group_rittal_softfax_receive]
; контекст программного факса.
exten => fax,1,NoOp(group_rittal_softfax from ${CALLERID(NUM)})

; получим имя файла вида fax-[номер факса].tif
exten => fax,n,Set(GLOBAL(FAXCOUNT)=${IF($["${GLOBAL(FAXCOUNT)}"=""]?0:${GLOBAL(FAXCOUNT)})})
exten => fax,n,Set(GLOBAL(FAXCOUNT)=$[${GLOBAL(FAXCOUNT)} + 1])
exten => fax,n,Set(FAXCOUNT=${GLOBAL(FAXCOUNT)})
exten => fax,n,Set(FAXFILE=/tmp/faxes/fax-${FAXCOUNT}.tif)

; принимаем факс в файл
exten => fax,n,ReceiveFax(${FAXFILE})
exten => fax,n,Hangup()

; когда факс положил трубку, займемся анализом того,
; чего он наполучал
exten => h,1,NoOp(fax hangup)
; получим статус приема
exten => h,n,GotoIF($["${FAXOPT(status)}" != "SUCCESS" ]?finish)

; статус приема - успешный.
; теперь необходимо передать это имя файла скрипту с описанием действия
; скрипт принимает следующие параметры:
; -f=имя файла -m=действие -p=параметр
; -m=del - удалить файл
; -m=mail -p="адрес" - отправить по email
; -m=print -p="имя принтера" - распечатать
; на первом этапе мы выполним все три, потом будем выбирать

; печатаем
exten => h,n,NoOp(${SHELL(php /var/lib/asterisk/rittal/fax_work.php -f ${FAXOPT(filename)} -m print -p printer1)})
; отправляем
exten => h,n,NoOp(${SHELL(php /var/lib/asterisk/rittal/fax_work.php -f ${FAXOPT(filename)} -m mail -p user@rittal.ru)})
; удаляем
exten => h,n,NoOp(${SHELL(php /var/lib/asterisk/rittal/fax_work.php -f ${FAXOPT(filename)} -m del)})
; финишируем
exten => h,n(finish),NoOp(finish fax hangup)

Скрипт выглядит так (отправку емейла я взял отсюда, остальное написал сам):

<?php
date_default_timezone_set
('Europe/Moscow');
$args=getopt("f:m:p:");

// проверяем, что задан параметр "файл" и файл существует
if(!isset($args['f'])) die("use -f to give file name\n"); 
if(!
file_exists($args['f'])) die("file '".$args['f']."' is not exists\n");

// проверяем, что задан параметр mode
if(!isset($args['m'])) die("use -m to give mode name\n");

switch (
$args['m'])
{
    case 
'del':
        
// удаление файла
        
unlink($args['f']);
        break;
    case 
'mail':
        
// отправка емейла
        
if( (!isset($args['p'])) || ($args['p']==''))  die("use -p to give dest mail\n");
        
        
$to=$args['p']; // кому
        
$subject="Fax received ".date("d.m.Y H:i:s"); // тема
        
$random_hash md5(date('r'time())); 
        
// Заголовки
        
$headers "From: fax@rittal.ru\r\nReply-To: postmaster@rittal.ru"
        
$headers .= "\r\nContent-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\"";
        
$attachment chunk_split(base64_encode(file_get_contents($args['f']))); 
        
        
$body="";
        
$body .="\r\n".'--PHP-mixed-'.$random_hash;
        
$body .="\r\n".'Content-Type: multipart/alternative; boundary="PHP-alt-'.$random_hash.'"';
        
$body .="\r\n";
        
$body .="\r\n".'--PHP-alt-'.$random_hash
        
$body .="\r\n".'Content-Type: text/plain; charset="iso-8859-1"';
        
$body .="\r\n".'Content-Transfer-Encoding: 7bit';
        
$body .="\r\n";
        
$body .="\r\n".'Please, see fax message in attachment';
        
$body .="\r\n";
        
$body .="\r\n".'--PHP-alt-'.$random_hash.'--';
        
$body .="\r\n".'--PHP-mixed-'.$random_hash
        
$body .="\r\n".'Content-Type: application/tiff; name="fax.tiff"'
        
$body .="\r\n".'Content-Transfer-Encoding: base64'
        
$body .="\r\n".'Content-Disposition: attachment'
        
$body .="\r\n";
        
$body .="\r\n".$attachment;
        
$body .="\r\n".'--PHP-mixed-'.$random_hash.'--'
        
$body .="\r\n";
        
        
mail$to$subject$body$headers );
        
        break;
    case 
'print':
        
// печать файла на принтере
        
if( (!isset($args['p'])) || ($args['p']==''))  die("use -p to give printer name\n");
        
exec('tiff2ps "'.$args['f'].'" | lpr -P'.$args['p']);
        break;
        
    default:
         die(
"wrong mode!\n");
    
}
?>