.call files

Есть много способов прострелить себе ногу совершить исходящий вызов в Астериске:
1. Из диалплана
2. Из командной строки Originate
3. AMI (Originate)
4. Call файлы
Вот о последних, зачем они и с чем их едят мы и поговорим)
Заметка для себя, чуть менее чем полностью содрана с других источников.

.call файлы — Текстовый файл соответствующий определенному синтаксису
Синтаксис .call файлов
Channel: Канал, который будет использоваться для исходящего вызова.
CallerID: Name CallerID,
MaxRetries: Количество попыток перед тем, как вызов будет считаться неудачным (не включая первую попытку, т.е. 0 = означает совершить 1 попытку вызова). Значение по умолчанию: 0.
RetryTime: Количество секунд между попытками вызова, не стоит очень часто ломиться на недоступный телефон. Значение по умолчанию: 300 (5 минут)
WaitTime: Количество секунд для ожидания ответа на вызов. Значение по умолчанию: 45.
Account: Установка поля “account code”для записи в CDR.
Если первый участник вызова ответил, то далее описываем с кем и как его соединить
Context: Контекст в файле extensions.conf.
Extension: Название екстеншена в extensions.conf..
Priority: Номер приоритета для екстеншена, с которого нужно начать выполнение.
Set: Установка переменных канала для использования их в логике обработки вызова на заданный екстеншен
Application: Имя приложения Asterisk, которое необходимо выполнить (используется вместо параметров context, extension и priority).
Data: Параметры для запускаемого приложения.
AlwaysDelete: Yes/No – Если время модификации .call файла больше текущего, то этот файл не будет удален.
Archive: Yes/No – Переносить или нет .call файл в поддиректорию «outgoing_done» с установленным значением поля «Status: значение», где значение может быть: Completed, Expired или Failed.

Для совершения вызова в .call файле как минимум должно быть определено одно приложение или екстеншен, наряду с названием канала, с которого совершается вызов.

Как заставить это работать:
Просто помещаем наш call файл в директорию (по умолчанию): /var/spool/asterisk/outgoing
Если в файле конфигурации modules.conf установлено: autoload=no, убедитесь, что у Вас загружен модуль pbx_spool.so, иначе работа с .call файлами производиться не будет .
При обнаружении .call файла, Asterisk немедленно создаст канал для вызова, который будет соединен с указанным екстеншеном и приоритетом из плана набора. Все эти параметры будут взяты из .call файла.
Если дата модификации .call файла больше текущей даты на сервере, то Asterisk отложит обработку данного файла до тех пор, пока время модификации этого файла не сравняется или не станет больше текущего времени.

Специальный екстеншен ‘failed’

Если на вызов не ответили, и существует стандартный екстеншен с именем failed и команда с приоритетом 1 в заданном (в .call файле) контексте, управление будет передано этой команде
Замечание 1: Это работает, если вы совершаете вызов с использованием полей context, extension и priority, и естественно не будет работать, если используется приложение для совершения вызовов.
Замечание 2: В этом екстеншене довольно удобно обрабатывать CDR поле UserField, занося туда номер телефона, до которого не удалось дозвониться, с помощью команды: SetCDRUserfield().
Замечание 3: Переменная канала ${REASON} принимает значение, которое определяет причину, по которой попытка вызова закончилась неудачей.
Пример1:

строка в .call файле:
Set: PassedInfo= 15551234567-moreinfo-evenmoreinfo

в extensions.conf:
exten => failed,1,Set(NumberDialed=${CUT(PassedInfo,,1)})
exten => failed,n,SetCDRUserField(${NumberDialed})

Как сообщают источники, из этого экстеншена не работает Dial, нужно изобретать велосипед(уже придумали)
exten => failed,1,Dial(SIP/[email protected])

Channel: Local/[email protected]
Callerid: 9998877
Context: outgoing_to_112233
Extension: s
Priority: 1

[autocaller]
exten => 1,1,Macro(call6003user,6003)

[macro-call6003user]
exten => s,1,Dial(SIP/${ARG1},15,t)
exten => s,n,Goto(s-${DIALSTATUS},1)
exten => s-NOANSWER,1,Dial(SIP/[email protected])
exten => s-NOANSWER,n,VoiceMail(${ARG1},u)
exten => s-NOANSWER,n,Hangup()
exten => s-BUSY,1,VoiceMail(${ARG1},b)
exten => s-BUSY,n,Hangup()
exten => _s-.,1,Goto(s-NOANSWER,1)

Не забывайте к переменным добавлять префикс “_” или “__” , для того, чтобы они были видимы в создаваемых (“дочерних”) каналах!
Используйте приложения DBGet и DBPut, если возникают проблемы с передачей значений переменных.

Создание и перемещение .call файлов.
Вследствие того, что сервер Asterisk может прочитать эти файлы в любое время (например, когда он еще записан только наполовину), не создавайте их непосредственно в директории, где их читает Asterisk (/var/spool/asterisk/outgoing). Процедура их создания должна быть примерно следующей:
Создайте Ваш . call файл в какой-либо другой временной директории, например, в: /var/spool/asterisk/temp1234
Установите владельца и группу для этого файла, командой: chown asterisk:asterisk /var/spool/asterisk/temp1234 (если файл temp1234 создан от пользователя root, а Asterisk работает от системного пользователя asterisk).
Переместите этот файл, командой: mv /var/spool/asterisk/temp1234 /var/spool/asterisk/outgoing

Это будет корректно работать в большинстве случаев, т.к. в Unix операция перемещения файла в пределах одного раздела (команда mv) просто перемещает «inode» – указатель на файл – и он появиться в указанной директории уже сразу целиком, что предотвращает ситуацию, когда Asterisk считывает частично записанный файл. (Обратите внимание: Что все вышесказанное относиться только к тому случаю, если источник и точка перемещения файла находятся в пределах одного логического раздела, иначе, будет использоваться эквивалентная комбинация из команд «cp» и «rm», что может привести к вышеописанной проблеме.)
Замечание: Использование команды копирования файла (cp) не является безопасным методом для добавления .call файла в директорию сервера Asterisk для его последующей обработки, т.к. он может быть прочитан другой программой в середине процесса его копирования, когда он еще не полностью скопирован.

.call файлы и CDR записи

Предотвращение отсутствия CDR записей при использовании .call файлов
Для этого используйте один из вариантов для совершения вызовов:
a) Используйте параметры Context/Extension/Priority в .call файле вместо непосредственного указания приложения для выполнения: Application/Data.
b) Совершайте вызовы через локальный канал вместо непосредственного указания имени канала для вызова абонента.
В противном случае Asterisk не будет выполнять ту часть внутренней логики, которая отвечает за протоколирование вызовов и, следовательно, CDR записи не будет сгенерированы. Когда вы используете для совершения вызова связку: Context/Extension/Priority, вы просто как бы выполняете безусловный переход в определенную точку плана набора, как будто вызов поступил в нее обычным образом, а в этом случае все вызовы будут протоколироваться обычным образом.

Номер вызываемого абонента не будет сохранен в CDR записи. Если Вам необходима эта информация в последующей обработке CDR записей, Вы можете установить поле CallerID в .call файле в значение этого номера и он будет сохранен в CDR записи. Однако, в этом случае, абоненту, которого Вы вызываете, будет высвечиваться, что ему звонит он сам (его же номер телефона), что не имеет особого смысла и может вводить их в заблуждение. Лучшем решением этой задачи будет указание этого номера в переменной канала, при помощи параметра “Set:” в.call файле с последующим занесением его в поле UserField CDR записи в логике плана набора отвечающей за вызов абонентов.

Примеры:
Cовершаем вызов на номер 14109850123 с SIP телефона с именем 101:

Channel: SIP/101
MaxRetries: 1
RetryTime: 60
WaitTime: 30
#
# Предполагается, что обработка исходящих вызовов происходит в контексте [outgoing]
#
Context: outgoing
Extension: 14109850123
Priority: 1

Вызов внутреннего или внешнего екстеншена и соединение его с AGI скриптом для отправки сообщения.

Channel: Local/[email protected]
MaxRetries: 0
RetryTime: 15
WaitTime: 15
Application: AGI
Data: myagi.agi

Как задать выполнение .call файла в определенное время.
Файлы, у которых дата модификации файла больше текущего времени, будут игнорироваться до того момента, как их дата модификации не станет равной или меньшей системного времени на сервере. Просто создайте файл, например, в директории: /var/spool/asterisk/tmp, модифицируйте его параметр “mtime”, используя команду «touch», и переместите его в директорию, где их “ждет” сервер asterisk…
После того как создали сам call файл берем и меняем дату его создания, шаблон даты такой:
ГОДМЕСЯЦДЕНЬЧАСЫМИНУТЫ.СЕКУНДЫ (внимание: перед секундами стоит символ точки, это так и нужно, а не опечатка).
Для примера выставим дату в будущем, скажем это 09.07.2013 19:18:55:

$ date
Mon Mar 19 13:52:30 EET 2013
$ cd /var/spool/asterisk/outgoing
$ touch -t 1307091918.55 /var/spool/asterisk/tmp/blah
$ mv /var/spool/asterisk/tmp/blah .
$ ls -l blah

Пример на Bash: выполнить .call файл через 100 секунд:

# Получаем текущее время в секундах
NOW=`date +%s`
# добавляем к ней 100 секунд
let NOW=$NOW+100
# создаем timestamp (строку с датой и временем), которую потом используем в команде 'touch -t' (между %M. %S не должно быть пробелов)
TOUCH_TMSP=`date -d "1970-01-01 $NOW sec GMT" +%Y%m%d%H%M. %S`
# выполняем команду “touch”
touch -t $TOUCH_TMSP blah

Так же с помощью call файлов можно генерировать callback звонки

Литература:

  1. на Ангельском
  2. на Русском
  3. Практическое применение

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