Man вики
Регистрация
Advertisement

Помимо двух настоящих извращений - хоккея на траве и балета на льду,существует и третье - диалап через ip-телефонию. (народная мудрость)

Задача

  1. Организовать автоматизированный шлюз для пересылки документов полученных через электронную почту, адресатам на типовые факсовые аппараты подключенные в телефонную сеть.
  2. Обеспечить статистику и контроль доставки с ведением базы данных по событиям

Требования к системе

  • Наличие доступа по протоколу POP3 к выделенному для этой цели почтовому ящику. Ящик не должен использоваться для других целей, все письма попадающие в него будут удаляться.
  • Наличие доступа к телефонной сети посредством VoIP (IAX2,SIP) с поддержкой aLaw или uLaw или иных средств доступных для использования совместно с Asterisk.

Условия в примере

Реальный или виртуальный сервер на базе ОС Ubuntu Server 12.04 имеющий сетевой доступ к учетным записям:

  • IAX2 (VoIP Asterisk пользователь: user пароль: 123 адрес: 11.22.33.44)
  • POP3 (пользователь: user пароль: 123 адрес: mail.local)

Письма автоматически формируются платформой 1Сv82 по принципу:

  • Адрес получателя - efax@mail.local
  • Тема и содержимое не важно
  • Только одно почтовое вложение в формате pdf (средствами платформы 1с)

Имя вложения содержит всю необходимую информацию, например:

  • msk_0004567_84991112233-1_9-18_1-5.pdf где:
    • "_" - знак разделения значащих полей
    • msk - префикс базы 1с (филиала)
    • 0004567 - номер документа
    • 84991112233 - номер абонента (получателя факса). 1 - добавочный номер, если указан то до набрать в тоновом режиме (например прямой номер факса автомата)
    • 9-18 - время доступности факса у абонента с 9 до 18 часов
    • 1-5 - дни недели, когда доступен прием факса у абонента (с пн по пт)

Принцип работы

Логический

  1. Выполняется периодическая проверка почтового ящика и в случае обнаружения в нем писем они скачиваются системой
  2. Генерируется случайный уникальный код, который будет участвовать во всех этапах движения этого документа и попадет в статистику
  3. Из скачиваемых писем извлекаются вложения и складываются в папку входящих
  4. Из этой папки выбирается файл отвечающий требованиям к формату имени
  5. Из имени файла выделяются значащая информация и сохраняется в базу данных
  6. Файл отправляется на доставку факсовому серверу, сам файл перемещается в папку обработка
  7. Факсовый сервер на основании переданных параметров помещает факс в очередь на отправку
  8. Через виртуальный модем подключенный к серверу ИП телефонии производится дозвон до получателя
  9. С помощью синтеза голоса получатель уведомляется о сути звонка
  10. С помощью распознавания голоса в базу данных заносится информация от получателя (напр. ФИО, должность)
  11. По результату звонка в базу заносится информация об успешности или не успешности отправки факса с указанием причины
  12. На том-же основании файл перемещается в соответствующую папку

По компонентам

  • MySQL сервер для хранения статистики
  • Fetchmail забирает письма с внешнего почтового ящика по протоколу pop3 и передает их Procmail
  • Procmail (обработчик почтовых сообщений) передает тело письма программе ripmime, а затем запускает bash-скрипт обработки
  • uudeview извлекает из письма прикрепленный файл и сохраняет в папку входящих
  • bash-скрипт анализирует формат названия файла, передает файл в Hylafax, пишет в mysql полученную информацию
  • Hylafax (факс сервер) получив задание выполняет дозвон через iaxmodem, получателю факса
  • iaxmodem подключен к локальному серверу Asterisk (можно создать множество модемов)
  • Asterisk выполняет подключение к городской телефонной сети через voip протокол, обеспечивает голосовое приветствие
  • API Google используется для синтеза и распознавания голоса в момент ответа абонента, через ARI скрипты Asterisk

Подготовительные работы

Установка компонентов

apt-get update
apt-get install lamp-server^ asterisk iaxmodem hylafax-server postfix procmail fetchmail uudeview

Мастера установки спросят пароль для сервера mysql (запомним его), libvpb0 оставим по умолчанию 7, а для Postfix Configuration выберем Без настройки

Создание базы данных

Вся статистика работы факс-шлюза будет хранится в базе на mysql сервере.

  • Создадим новую базу faxstats
  • Войдем в консоль mysql и выполним запрос на создание базы и таблицы, а так-же назначим права доступа:
mysql -p

Скопируем и вставим

# Создаем базу faxstats
CREATE DATABASE faxstats 
CHARACTER SET utf8 
COLLATE utf8_general_ci;
# Тут назначим права и разрешим удаленное подключение к базе
# Пользователь faxstats
# Пароль isolda
grant usage on *.* to faxstats@localhost identified by 'isolda';
grant all privileges on faxstats.* to faxstats@localhost;
# Создаем таблицу mailtofax для событий получения файлов
USE faxstats;
CREATE TABLE
 mailtofax 
 (
  uniqid    TEXT(10),
  eventdate DATETIME,
  preffil   TEXT(8),
  id        TEXT(64),
  numbertel TEXT(64),
  namefile  TEXT(64),
  jobnumber INTEGER
  );
# Создадим таблицу asterstats для сохранения результатов распознавания голоса.
CREATE TABLE
 asterstats 
 (
  uniqid    TEXT(10),
  eventdate DATETIME,
  numbertel TEXT(64),
  namesotr  TEXT(254)
  );
# Создадим таблицу xferfaxlog для переноса в нее лога hylafax

CREATE TABLE
 xferfaxlog
 (
  eventdate   DATETIME,
  ENTRYTYPE   TEXT(32),
  COMMID      TEXT(32),
  MODEM       TEXT(32),
  JOBID       TEXT(8),
  JOBTAG      TEXT(32),
  USERID      TEXT(32),
  LOCALNUMBER TEXT(32),
  TSI         TEXT(32),
  PARAMS      TEXT(32),
  NPAGES      TEXT(8),
  JOBTIME     TIME,
  CONNTIME    TIME,
  REASON      TEXT(254),
  CIDNAME     TEXT(128),
  CIDNUMBER   TEXT(128),
  CALLID      TEXT(128),
  OWNER       TEXT(32),
  DCS         TEXT(254),
  JOBINFO     TEXT(254)
 );

exit

Почтовая часть

На данном этапе мы решаем задачу по подключению к почтовому, скачивание из него писем, извлечение из них вложений и запуска обработчика этих вложений

Пути и папки

  • Создадим папки для сохранения вложений
mkdir /home/efax/ && cd /home/efax/
mkdir IN PROC ERR OK

fetchmail получение почты

Сохраняем копию оригинального файл конфигурации, очищаем его и пишем свои параметры

cp /etc/fetchmailrc /etc/fetchmailrc.orig
echo ""> /etc/fetchmailrc
nano /etc/fetchmailrc

Внесем свои параметры

set daemon         10  # Проверка новых писем (в сек)

# Параметры подключения к почтовому ящику
poll mail.local        # Адрес сервера
proto pop3             # Протокол получения писем
user user              # Логин
pass 123               # Пароль
sslproto ""            # Не ругаться на сертификат
mda 'procmail -d %T'   # Передача управления procmail

Разрешаем запуск демона (службы)

echo "START_DAEMON=yes" > /etc/default/fetchmail
/etc/init.d/fetchmail restart

procmail обработка писем

Задача принять от fetchmail письмо и направить его в uudeview для извлечения вложений и сохранения их в папку входящих, а затем передать управление bash-скрипту.

nano /etc/procmailrc

Внесем параметры:

:0
* ^From:.*
{
 :0 f
 | uudeview -iq - -p /home/efax/IN/

 :0
 | /home/efax/mailtofax
}

Обработка вложений

Для выбора и обработки вложений создадим скрипт:

nano /home/efax/mailtofax
# Путь до папки с входящими
pathin=/home/efax/IN
# Путь до папки с обрабатываемыми документами
pathproc=/home/efax/PROC
# Шаблон (регулярное выражение) для выборки файлов
freg=".+_.+_.+\.pdf"
# Параметры базы mysql
dbuser=faxstats
dbpass=isolda
dbname=faxstats
dbtable=mailtofax

# Составляем список всех файлов соответствующих шаблону
lsfiles=`ls -tr /home/efax/IN| grep -P $freg`

for namefile in $lsfiles; do
IFS="_"
 set -- $namefile
# Разбираем имя файла на переменные
  preffil=$1
  id=$2
  numbertel=`echo $3|awk -F "-" '{print $1}'`
  numberdtmf=`echo $3|awk -F "-" '{print $2}'`
  worktime=$4
  workdays=$5
Сохраняем время и дату
eventdate=`date +"%Y/%m/%d %T"
`
# Перемещаем файл в обработку
mv "$pathin/$namefile" "$pathproc/$namefile"

# Генерим уникальный 10 значный ключ файла
uniqid=`head -c 10 /dev/urandom|cksum|awk '{print $1$1}'|head -c 10`

# Отправляем файл на доставку
istr=`sendfax -n -d "$numbertel*$uniqid*$numberdtmf" "$pathproc/$namefile"`
  jobnumber=`echo $istr|grep -Po "request id is \d+"|awk '{print $4}'`
echo "$uniqid;$eventdate;$preffil;$id;$numbertel;$namefile;$jobnumber" >> /var/log/mailfax.log
# Добавляем запись в базу
mysql -u$dbuser -p$dbpass -D $dbname -e "INSERT INTO $dbtable \
 (  uniqid,   eventdate,   preffil,   id,   numbertel,   namefile,   jobnumber) values \
 ('$uniqid','$eventdate','$preffil','$id','$numbertel','$namefile','$jobnumber');"

done

Делаем скрипт исполняемым

chmod +x /home/efax/mailtofax

Телефония

Локальный Asterisk сервер нужен для того, чтобы:

  1. Обеспечить виртуальным модемам постоянное подключение
  2. Управлять голосовыми приветствиями и логикой взаимодействия с получателем факса.
  3. Обеспечить маршрутизацию вызовов через один или несколько внешних транков

Настройка каналов

Создадим учетную запись IAX2 на нашем (локальном) asterisk сервере, для регистрации iaxmodem, а так-же транк для подключения к провайдеру IP телефонии (например тоже через IAX2 протокол) для совершения исходящих вызовов.

  • iaxmodem будет регистрироваться на номере 910 с паролем faxfax123
  • Во внешний мир наш сервер будет выходить через IAX2 транк с параметрами:
    • адрес сервера 11.22.33.44
    • имя пользователя user
    • пароль 123


копируем оригинальный файл, очищаем оригинальный файл и создаем свой

cp /etc/asterisk/iax.conf /etc/asterisk/iax.conf.orig
echo "" > /etc/asterisk/iax.conf
nano /etc/asterisk/iax.conf

Вносим свои параметры:

[general]
disallow=all
allow=alaw

# Для подключения модема серверу
[910]
host=dynamic
type=friend
secret=faxfax123
requirecalltoken=no
context=from-iaxmodem

# Для подключения сервера к внешнему миру
[iaxprovider]
type=peer
host=11.22.33.44
username=user
fromuser=user
secret=123
qualify=yes

Настройка плана набора

  • Для создания интерактивного меню с синтезом и распознаванием голоса для взаимодействия с абонентом, подключим Asterisk к API функциям работы с голосом от комании Google

Синтез и распознавание голоса в Asterisk

  • Создаем план набора (dialplan)
cp /etc/asterisk/extensions.conf /etc/asterisk/extensions.conf.orig
echo "" > /etc/asterisk/extensions.conf
nano /etc/asterisk/extensions.conf

Вносим свои параметры:

[from-iaxmodem]
# Выделяем из набора номер телефона, уникальный код и добавочный номер
exten => _X.,1,Set(dialnum=${CUT(EXTEN,"*",1)})
exten => _X.,n,Set(uniqid=${CUT(EXTEN,"*",2)})
exten => _X.,n,Set(dtmfnum=${CUT(EXTEN,"*",3)})

# Если в номере стоит добавочный то набрать его в тоновом режиме
exten => _X.,n,GotoIf($["${dtmfnum}" = ""]?itr)
exten => _X.,n,Dial(iax2/khb-jde27/${dialnum},,M(dtmfdial^${dtmfnum}))

# Звонок с интерактивным меню
exten => _X.,n(itr),Dial(iax2/khb-jde27/${dialnum},,M(priv^${dialnum}^${uniqid}^${dtmfnum}))

[macro-dtmfdial]
exten => _.,1,Answer
exten => _.,n,Wait(1)
exten => _.,n,SendDTMF(w${ARG1})

[macro-priv]
exten => _.,1,Answer
exten => _.,n,Wait(1)
exten => _.,n,AGI(say.php,"Здравствуйте‚!")
exten => _.,n,AGI(say.php,"скажите имя сотрудника!") #Запись услышанного
exten => _.,n,Record(/tmp/${UNIQUEID}.wav,3,20)  #Запись услышанного
exten => _.,n,AGI(say.php,"вы сказали")
exten => _.,n,Playback(/tmp/${UNIQUEID})
exten => _.,n,AGI(voice.php,/tmp/${UNIQUEID})
exten => _.,n,AGI(say.php,"я услышала")
exten => _.,n,AGI(say.php,"${VOICE}") 
exten => _.,n,System(/home/efax/asttosql "${VOICE}" ${ARG1} ${ARG2} ${ARG3})



Перезапускаем Asterisk

/etc/init.d/asterisk restart

Добавляем скрипт на добавление результата распознавания голоса в базу

nano /home/efax/asttosql
# Параметры базы mysql
dbuser=faxstats
dbpass=isolda
dbname=faxstats
dbtable=asterstats

eventdate=`date +"%Y/%m/%d %T"`
namesotr=$1
numbertel=$2
uniqid=$3


# Добавляем запись в базу
mysql -u$dbuser -p$dbpass -D $dbname -e "INSERT INTO $dbtable \
 (  uniqid,   eventdate,   numbertel,   namesotr) values \
 ('$uniqid','$eventdate','$numbertel','$namesotr');"

Делаем скрипт исполняемым

chmod +x /home/efax/asttosql

Факсовая часть

Настройка IAXMODEM

Создаем конфигурацию виртуального модема

nano /etc/iaxmodem/iaxmodem-cfg.ttyIAX1
device /dev/ttyIAX1
owner uucp:uucp
mode 660
port 4570
refresh 300
server 127.0.0.1
peername 910
secret faxfax123
codec alaw

Запускаем виртуальный модем

/etc/init.d/iaxmodem start

Проверяем лог запуска

cat /var/log/iaxmodem/iaxmodem

Настройка hylafax Server

Запускаем мастер настройки

faxsetup

Отвечаем на все вопросы по умолчанию пока не появится вопрос:

Serial port that modem is connected to [ttyS0]?

Пишем имя порта ttyIAX1

Local identification string (for TSI/CIG) ["NothingSetup"]?

указываем название организации JDE и продолжаем отвечать на вопросы мастера, пока не появится запрос о добавлении второго модема Do you want to run faxaddmodem to configure another modem [yes]? . На него отвечаем No Перезапускаем hylafax

/etc/init.d/hylafax restart


(i) Для управления сервером и контроля состояния можно использовать некоторые полезные команды:

Посмотреть очередь

faxstat -s

Удалить из очереди задание с номером

faxrm номер

Быстро очистить всю очередь с полными правами

faxrm -a `faxstat -s | grep -Po "^\d+"|tr "\n" " "`

Статистика по факсам

  • Скрипт переноса лога hylafax в базу

nano /home/efax/mysqlhyla

#!/bin/bash
########### Параметры ############# 
# Путь до файла с логом
pathin=/var/spool/hylafax/log/xferfaxlog
# Параметры базы mysql
dbuser=faxstats
dbpass=isolda
dbname=faxstats
dbtable=xferfaxlog

# Переименовываем файл лога для исключения повторного считывания
rans=$RANDOM
mv $pathin $pathin-$rans

# Читаем лог и назначаем переменным значения полей разеденных табом 
cat $pathin-$rans| while read line; do
IFS=`printf "\t"`
 set -- $line

eventdate=`date -d$1 "+%Y-%m-%d %T"`; shift
ENTRYTYPE="$1"; shift
COMMID="$1"; shift
MODEM="$1"; shift
JOBID="$1"; shift
JOBTAG="$1"; shift
USERID="$1"; shift
LOCALNUMBER="$1"; shift
TSI="$1"; shift
PARAMS="$1"; shift
NPAGES="$1"; shift
JOBTIME="$1"; shift
CONNTIME="$1"; shift
REASON="$1"; shift
CIDNAME="$1"; shift
CIDNUMBER="$1"; shift
CALLID="$1"; shift
OWNER="$1"; shift
DCS="$1"; shift
JOBINFO="$1"; shift

mysql -u$dbuser -p$dbpass -D $dbname -e "INSERT INTO $dbtable \
  (  eventdate,   ENTRYTYPE,   COMMID,   MODEM,   JOBID,   JOBTAG,   USERID,   LOCALNUMBER,   TSI,   PARAMS,   NPAGES,   JOBTIME,   CONNTIME,   REASON,   CIDNAME,   CIDNUMBER,   CALLID,   OWNER,   DCS,   JOBINFO) values \
  ('$eventdate','$ENTRYTYPE','$COMMID','$MODEM','$JOBID','$JOBTAG','$USERID','$LOCALNUMBER','$TSI','$PARAMS','$NPAGES','$JOBTIME','$CONNTIME','$REASON','$CIDNAME','$CIDNUMBER','$CALLID','$OWNER','$DCS','$JOBINFO');"

done

сделаем его исполняемым

chmod +x /home/efax/mysqlhyla
Advertisement