вторник, 21 июня 2016 г.

Asterisk. Выполнение скрипта при ответе абонента.

Имеется Asterisk. Необходимо реализовать функционал, при котором при ответе абонента запускается и выполняется скрипт php с передачей скрипту в качестве аргументов номера вызываемого и вызывающего абонентов.

Реализуется это с помощью конструкции в диалплане (в файле extensions.conf):
[from_12]
exten => 293ХХХХ,1,Dial(SIP/${EXTEN},120,M(answerscript^${CALLERID(num)}^${EXTEN}))
Опция M в команде Dial заставит Asterisk выполнить макрос (в нашем случае answerscript)  и передать макросу ряд аргументов. Аргументы отделяются между собой символом домика (^).

Макрос запуска внешнего скрипта /var/www/html/test.php описывается в отдельном контексте:
[macro-answerscript]
exten => s,1,System(/usr/bin/php -f /var/www/html/test.php ${ARG1} ${ARG2} )

понедельник, 13 июня 2016 г.

Настройка Fax-to-MAIL во Freeswitch 1.6.
Использование Freeswitch для автоматической отправки факсов.

Fax-to-MAIL

1. Установка ImageMagick – пакета, занимающегося конвертированием изображений
# yum install ImageMagick
Теперь конвертировать документ tiff в pdf можно так:
# convert <имя файла на входе>.tiff -resize 100% -monochrome <имя на выходе>.pdf
Эта возможность понадобиться для преобразования принятого факса к формату, удобному для просмотра. (tiff – формат, в котором происходит прием факса в Freeswitch, pdf – нужный нам формат)

2. Установка mutt – удобной программы отправки почтовых сообщений. Отлично работает в командной строке, поддерживает отправку вложений.
# yum install mutt 
Создаем файл конфигурации:
# touch ~/.muttrc
# nano ~/.muttrc
Содержимое файла:
# My email address
set pop_user="admin@mail.ttk"

# My email account password
set pop_pass="xxxxxx"

# Too many email headers make reading a message difficult
ignore *
unignore From: To: Cc: Subject: Date: #Only these are shown in the header

set from="admin@ttk.ru"
set use_from=yes
set envelope_from="yes"
set realname='Network Administrator'
Отправка простого письма с помощью mutt 
# echo "This is the message body" | mutt -s "Тест" admin@yandex.ru
Отправка письма с вложением
# echo "This is the message body" | mutt -s "Тест" -a "/tmp/123.pdf" -- admin@yandex.ru

Для того чтобы Freeswitch использовал наши данные, прописанные в файле .muttrc, для отправки писем, необходимо поместить файл .muttrc в домашнюю папку пользователя freeswitch.
У пользователя freeswitch домашняя папка - /usr/local/freeswitch
# touch /usr/local/freeswitch /.muttrc
# nano /usr/local/freeswitch /.muttrc
Помещаем в файл, созданную ранее конфигурацию
Выставляем права доступа:
# chown freeswitch:freeswitch /usr/local/freeswitch/.muttrc
# chmod 644 /usr/local/freeswitch/.muttrc

3. Создаем скрипт отправки факса по электронной почте
# mkdir /usr/bin/script_freeswitch
# touch /usr/bin/script_freeswitch/sendmailfax.sh
# chmod +x /usr/bin/script_freeswitch/sendmailfax.sh
# chmod 777 /usr/bin/script_freeswitch/sendmailfax.sh
# nano /usr/bin/script_freeswitch/sendmailfax.sh
На вход скрипта получаем перечень e-mail адресов для отправки и файл с полным путем, который необходимо отправить.
Содержимое файла:
#!/bin/bash
# $1  - email адреса через запятую
# $2  - название файла

#получаем базовое имя файла
FNAME=`basename $2 | rev | cut -c 6- | rev`
#получаем путь к файлу
PFNAME=`echo "${2%/*}"`

#Конвертируем файл в PDF
convert $2 -resize 100% -monochrome $PFNAME"/"$FNAME.pdf

#перебираем адреса и отправляем почту
IFS=',' read -ra ARR <<< `echo $1`
for (( i=0; i < `echo ${#ARR[@]}`; i++ ))
do
   echo "Здравствуйте! Принят факс. Пересылаем на адрес ${ARR[$i]}." | \
     mutt -s "Принят факс" -a "$PFNAME"/"$FNAME.pdf" -- ${ARR[$i]}
done

# удаляем исходный файл
rm -f $2 #удаляем исходный файл

Использовать скрипт нужно так:
/usr/bin/script_freeswitch/sendmailfax.sh bob@yandex.ru,post@mail.ru, /tmp/12345.tiff
В этом примере мы файл 12345.tiff будем конвертировать в pdf и отправлять на адреса bob@yandex.ru и post@mail.ru.

4. Определяем папку, в которую будут складываться пришедшие на наш номер факсы. 
Для конкретики будем считать, что номер, на котором работает Fax-to-mail – 3479938103. Имя папки  для временного хранения факсов будет такое же как и номер телефона.
# mkdir /tmp/3479938103
# chmod 777 /tmp/3479938103/

5. Общее конфигурирование Freeswitch
# cd /usr/local/freeswitch/conf/
Вносим общие правки в конфиг факса:
# nano autoload_configs/spandsp.conf.xml
Меняем
        <param name="ident"             value="SpanDSP Fax Ident"/>
        <param name="header"            value="SpanDSP Fax Header"/>
На
        <param name="ident"             value="Fax TTK"/>
        <param name="header"            value="Fax TTK Header"/>
Рестартуемся
# systemctl restart freeswitch

Для конфигов номеров fax-to-mail создадим отдельную папку в конфигурации:
# mkdir dialplan/supportsvttk/fax

В файл, определяющий план набора при входящем вызове помещаем директиву, обязывающую просматривать все файлы из каталог fax:
# nano dialplan/supportsvttk/10_in.xml
<X-PRE-PROCESS cmd="include" data="fax/*.xml"/>

6. Создаем файл описания номера отправки fax на e-mail:
# touch dialplan/supportsvttk/fax/3479938103.xml
# nano dialplan/supportsvttk/fax/3479938103.xml
Содержимое файла:
        <include>
        <extension name="test_3479938103">
        <condition field="destination_number" expression="^(3479938103)$">
             <action application="set" data="fax_ident=Fax 3479938103"/>
             <action application="set" data="fax_header=Fax 3479938103 HEADER"/>
             <action application="answer"/>
             <action application="playback" data="silence_stream://2000"/>
                          <action application="set" data="api_hangup_hook=system /usr/bin/script_freeswitch/sendmailfax.sh bob@yandex.ru,post@mail.ru, /tmp/3479938103/${strftime(%Y-%m-%d-%H-%M-%S)}-${caller_id_number}.tiff"/>                <action application="rxfax" data="/tmp/3479938103/${strftime(%Y-%m-%d-%H-%M-%S)}-${caller_id_number}.tiff"/>
             <action application="hangup"/>
        </condition>
        </extension>
        </include>
При попадании в этот план набора через 2000 мс паузы (в трубке вызываемого абонента слышна тишина), будет стартовать прием факса. 
Факс будет принят с номером содержащим дату приемки факса и номер вызывающего абонента. После того, как вызов завершиться (наступит действие api_hangup_hook), выполниться команда: 
/usr/bin/script_freeswitch/sendmailfax.sh bob@yandex.ru,post@mail.ru, /tmp/3479938103/${strftime(%Y-%m-%d-%H-%M-%S)}-${caller_id_number}.tiff, отправляющая принятый файл на электронные адреса.
Выставляем права доступа на созданные файлы и папки:
# chown -R freeswitch:freeswitch /usr/local/freeswitch/conf/
# chmod -R 770 /usr/local/freeswitch/conf/
Перечитываем конфигурацию Freeswitch
# fs_cli -x "reloadxml"


Автоматическая отправка факса без факсового аппарата

Для отправки факсов создадим несколько контекстов в конфигурации Freeswitch:
<context name="faxout">
   <extension name="send">
       <condition field="destination_number" expression="^(.*):(.*)$" break="on-true">
            <action application="answer"/>
            <action application="tone_detect" data="fax 1100 r +3000 transfer fax XML faxoutnow"/>
            <action application="playback" data="ttk/fax_payload_mono.wav"/>
            <action application="set" data="execute_on_fax_failure=system /usr/bin/script_freeswitch/fax_result.sh $1 $2 bad '\\\${fax_result_text}' "/>
            <action application="set" data="execute_on_fax_success=system /usr/bin/script_freeswitch/fax_result.sh $1 $2 ok '\\\${fax_result_text}' "/>
            <action application="txfax" data="$1"/>
            <action application="hangup"/>
       </condition>
   </extension>
</context>

<context name="faxoutdtmf">
   <extension name="send">
       <condition field="destination_number" expression="^(.*):(.*):(.*)$" break="on-true">
            <action application="tone_detect" data="fax 1100 r +3000 transfer fax XML faxoutnow"/>
            <action application="playback" data="silence_stream://300"/>
            <action application="send_dtmf" data="$3"/>
            <action application="set" data="execute_on_fax_failure=system /usr/bin/script_freeswitch/fax_result.sh $1 $2 bad '\\\${fax_result_text}' "/>
            <action application="set" data="execute_on_fax_success=system /usr/bin/script_freeswitch/fax_result.sh $1 $2 ok '\\\${fax_result_text}' "/>
            <action application="txfax" data="$1"/>
            <action application="hangup"/>
       </condition>
   </extension>
</context>

<context name="faxoutnow">
   <extension name="fax">
       <condition field="destination_number" expression="^fax$" break="on-true">
            <action application="set" data="execute_on_fax_failure=system /usr/bin/script_freeswitch/fax_result.sh $1 $2 bad '\\\${fax_result_text}' "/>
            <action application="set" data="execute_on_fax_success=system /usr/bin/script_freeswitch/fax_result.sh $1 $2 ok '\\\${fax_result_text}' "/>
            <action application="txfax" data="$1"/>
            <action application="hangup"/>
       </condition>
   </extension>
</context>

Контекст faxout используется для дозвона абоненту, проигрыванию ему сообщения типа «Вас приветствует компания такая-то, примите пожалуйста факс» и затем передачи абоненту факса.
Контекст faxoutdtmf будет использоваться для дозвона на номер и набора добавочного номера, а затем отправку факса.
Контекст faxoutnow используется в случае, если при установлении соединения через контексты faxout или faxoutdtmf был детектирован сигнал факса, то система сама перебросит вызов в контекст faxoutnow и отправит факс.
После отправки факса будет запущен скрипт /usr/bin/script_freeswitch/fax_result.sh, который получит на вход переменные, по которым можно определить результат отправки факса и принятии решения о повторной отправке.

Сообщение «Вас приветствует компания такая-то, примите пожалуйста факс» нужно поместить во вновь созданную папку:
# mkdir /usr/local/freeswitch/sounds/en/us/callie/ttk/
помещаем туда файл wav:
/usr/local/freeswitch/sounds/en/us/callie/ttk/fax_payload.wav
Даем права
# chown -R freeswitch:freeswitch /usr/local/freeswitch/sounds/en/us/callie/ttk
# chmod -R 770 /usr/local/freeswitch/sounds/en/us/callie/ttk
Рестартуемся
# systemctl restart freeswitch.service
Теперь к этому файлу можно обратиться в плане набора так:
<action application="playback" data="ttk/fax_payload_mono.wav"/>

Для отправки факса будем использовать команду originate 
В нашем случае команда без донабора добавочного будет выглядеть так:
fs_cli -x "originate {origination_caller_id_name=9735049,origination_caller_id_number=9735049}sofia/gateway/gw-si3000/3031101 /tmp/faxout/test_fax.tiff:121 XML faxout"
Командой устанавливается соединение с номером 3031101 через шлюз gw-si3000. При этом используется АОН 9735049.
Далее вызов передается контексту faxout с параметрами:
/tmp/faxout/test_fax.tiff:121
Первая часть этой строки – это имя файла, вторая часть – это идентификатор факсового сообщения, который я использую для дальнейшей обработки в скриптах, что бы убедиться, что факс дошел. Если факс вдруг не будет передан, то я об этом узнаю.

Команда при использовании донабора будет такая:
fs_cli -x "originate {origination_caller_id_name=9735049,origination_caller_id_number=9735049}sofia/gateway/gw-si3000/3031101 /tmp/faxout/test_fax.tiff:121:123 XML faxoutdtmf"
Здесь так же происходит вызов номера 3031101, но при этом передача вызова производиться в контекст faxoutdtmf. При этом в контекст faxoutdtmf передается строка:
/tmp/faxout/test_fax.tiff:121:123
Первая часть – это файл для отправки
Вторая часть – это идентификатор факса, необходимый в результирующих скриптах
Третья часть – нужный нам добавочный номер.

В результате выполнения команды originate, Freeswitch вернет нам результат принятия задачи и сообщит идентификатор SIP сессии:
Пример:
+OK 02910e93-e8bd-4c45-9671-5db5a8e568eb
Если с вызываемым абонентом соединение не установилось, то команда вернет ошибку и описание
Пример
+ERR User_busy

Для успешной отправки факса и для исключения искажений, необходимо правильно подготовить файл для передачи по факсу.
Команда, преобразующая файл в «правильный» формат такая:
convert -density 204x98 -units PixelsPerInch -resize 1728x1186\! -monochrome -compress Fax <имя_исх_файл> <выходной_файл>.tiff
Исходный файл изображения должен иметь вертикальную ориентацию и иметь соотношение сторон 1186х1728. Команда успешно справляется с конвертированием исходных файлов форматов JPG, JPEG. PDF, TIF, TIFF