Asterisk автодзвінок (auto-dial out) та зворотній дзвінок (callback) з використанням AGI, blog

Мережі, налаштування обладнання, мережеві послуги.

Автообзвон

Є завдання, реалізація яких можлива через автоматичний обдзвон. Наприклад?

Наприклад ви сис.адмін, у вас є локальна мережа і купа обладнання в ній, але ви ж не 24/7 на роботі, а раз так, то в мережі може щось статися, наприклад подія в системі моніторингу, а вас немає на робочому місці. Звичайно можна відправляти собі SMS, якщо така можливість є, а маючи серверAsterisk можна і зателефонувати і самому собі розповісти що ж трапилося 😉

Отже, вважаємо що у вас вже є встановлений і налаштований серверAsterisk, який має вихід у місто.

Щоб зробити автоматичний дзвінок нам знадобляться такі речі:

  • сформувати call файл
  • мати в діалплані (dialplan (визначається в /usr/local/etc/asterisk/extensions.conf)) контекст (context) зі списком дій

Почнемо з call файлу, його основний синтаксис:

  • Channel: - Який канал використовувати для дзвінка
  • CallerID: "name" - Встановити Caller ID, простіше сказати тут ми можемо виставити АОН (номер з якого ми дзвонимо).
  • MaxRetries: — Максимальна кількість спроб додзвонитися, за замовчуванням 0, що є однією спробою.
  • RetryTime: — Час у секундах між спробами додзвону за замовчуванням 300 (5 хвилин).
  • WaitTime: — Скільки секунд очікуємо підняття трубки за промовчанням 45.
  • Context: - Який контекст використовуємо з extensions.conf
  • Extension: - Який екстеншн використовуємо у вибраному контексті (так само в extensions.conf).
  • Priority:

— Із якого пріоритету починаємо.

Я навів не повний перелік, повний перелік доступний тут. Особисто я для кожногономери, створюю свій контекст в extensions.conf .

Відповідно знаючи синтаксис, ми тепер зможемо сформувати call файл, на прикладі дзвінка через SIP канал:

Для тих, хто в танку 🙂 розберемо call файл рядково:

  • зателефонувати на SIP номер 89161112233 через провайдера sip-provider (ім'я /usr/local/etc/asterisk/sip.conf для виходу в місто)
  • використовувати АОН 9998877
  • Максимальна кількість спроб дозвону 2
  • Пауза між спробами 20 секунд
  • Чекати на підняття трубки 60 секунд
  • Використовувати контекст (context) з ім'ям outgoing_to_89161112233
  • Починати з екстеншену (ext) s
  • І починати з пріоритету 1 в екстеншені s

Сформувавши call файл, його необхідно покласти в папку: /var/spool/asterisk/outgoing/ серверAsterisk виявивши в цій папці файл відразу спробує відпрацювати його.

Відразу скажу, що можна затримати обробку файлу, тобто. затримати вих. дзвінок і відкласти його на певний час.

СерверAsterisk дивиться на дату створення call файлу і якщо змінити дату створення на дату в майбутньому, тоAsterisk не буде відпрацьовувати call файл, доки не настане ця дата.

Як це зробити ? Дуже просто, для цього скористаємося командою touch, яка є у всіх unix системах.

Після того як створили сам call файл беремо та змінюємо дату його створення, шаблон дати такий:

РІК МІСЯЦЬ ДЕНЬ ГОДИННИХ ХВИЛИН. СЕКУНДИ ( увага: перед секундами стоїть символ точки, це так і потрібно, а не друкарська помилка ).

/usr/bin/touch -t 1007091918.55 /path/to/call/file.call

Дата створення call файлу зміниться і якщо перемістити файл у /var/spool/asterisk/outgoing/, то відповідноAsterisk його не обробить дотидоки не настане виставлена ​​дата.

Порада: генерувати call файл краще в якійсь tmp директорії, виконувати над ними всі необхідні дії і потім мувіть (переносити) в /var/spool/asterisk/outgoing/.

Тепер подивимося на сам контекст (context), для системи моніторингу він може бути таким:

Виходячи з даного контекстуAsterisk додзвонившись до 89161112233 (людина взяв трубку) виконає таке:

  • підніме трубку зі свого боку
  • секунду зачекає
  • програє записані вами звукові файли (повні шляхи до файлів вказані)
  • повісить трубку

Як записати голосові файли (що ви будете програвати) ви можете дізнатися з цієї статті.

Після того, як Asterisk повністю відпрацює call файл, він його видаляє з директорії /var/spool/asterisk/outgoing/ .

Спеціальний екстеншен 'failed ' Якщо на виклик не відповіли, і існує стандартний екстеншен з ім'ям failed та команда з пріоритетом 1 у заданому (у .call файлі) контексті, керування буде передано цій команді.

Може з'явиться ще одне завдання, а саме: якщо при автододзвон трубку так і не підняли, то відразу набрати інший номер. Приклад такої конструкції:

  • спочатку набираємо внутрішній SIP номер (6003) людини
  • якщо внутрішній SIP номер не відповідає/зайнятий/недоступний – набираємо мобільний номер

Здається, що може бути простіше, написати:

А ось тут і з'ясувалося, що не все так просто. На таке дійство ви в консолі (виставивши core set verbose 3) побачите подібне повідомлення:

— Executing [failed@dialsip:1] Dial(«OutgoingSpoolFailed», «SIP/6003») у новому стику [Feb 11 16:57:44] WARNING[94371]: channel.c:3441 ast_request: No translation path exists for channeltype SIP (native 65535) to 0 [Feb 11 16:57:44] WARNING[94371]: app_dial.c:1296 == Everyone is busy/congested at this time (1:0/0/1) == Auto fallthrough, канал 'OutgoingSpoolFailed' status is 'CHANUNAVAIL' [Feb 11 16:57:54 ] NOTICE[94371]: pbx_spool.c:356 attempt_thread: Call failed to go through, reason (8) Congestion (circuits busy)

Усі… приїхали…. Лазаючи за результатами пошуку в гугле я натикався на повідомлення:

Канал виходить OutgoingSpoolFailed і саме в нього намагається дзвонити та Dial та грати Playback. Як мені в failed зробити дзвінок на SIP і програти повідомлення?

Власне таке саме питання ставив собі і я сам, але відповіді на нього ні в Інеті ні в мене не було.

Так само як і я народ намагався реалізувати подібне через failed з Goto, System і т.п., але результат виходив таким самим - ніяким 🙁

Виходить starndart extention failed зробити набір (Dial) іншого номера не вийде…..

Я вже було подумав, що не доля і мені доведеться ловити DIALSTATUS, передавати його AGI скрипту (який ще й писати доведеться) і той вже вирішуватиме що з цим робити (створювати новий call файл або ще щось), але тут народився ще один варіант:

Створюємо call-файл вже трохи іншого змісту:

Де autocaller це назва контексту, а 1 -ця пріоритет у цьому контексті. Відповідно робимо у extensions.conf цей контекст:

Тим самим ми ніби набираємо вже не номер, а конкретний exten у контексті та в ньому передаємо виклик у макро, створюємо і макро, яке використовується в цьому контексті:

Власне, цей макро дає нам можливість вже керувати куди і в якому разі піде виклик.Приклад звичайно «грубий», але головне принцип, а далі вже ваша творчість 😉

І ось таким чином ми отримуємо результат.

Callback

Він працює за тим же принципом, що і описаний вище автообзвон, за деякими винятками:

  • генерація call файлу відбувається при дзвінку людини на номер, виділений підcallback.
  • у контексті (context) ми не просто програємо звукові, а пропонуємо користувачеві ввести номер, на який він хоче зателефонувати

Що нам буде потрібно в цьому випадку:

  • виділити номерcallback і створити контекст (context) під нього в extensions.conf .
  • «передати» дзвінок уAGI скрипт, який перевірить АОН того, хто дзвонить на предмет, чи дозволено цьому номеруcallback
  • якщоcallback дозволено, то сформує call файл.

AGI - цеA steriskG atewayI nterface.A steriskG atewayI nterface це можливість розширити функціоналAsterisk `а за допомогою використання скриптів на багатьох мовах програмування. Наприклад, Perl, PHP, C, Pascal, Bourne Shell.

Почнемо з номера, припустимо, це буде гір. номер 84955556677. Додамо в extensions.conf в контекст (context) куди надходять усі вхідні дзвінки:

Тобто. дзвінок на екстеншн (ext) 84955556677 буде переданийAGI скрипту callback.php , а потім дзвінок буде одразу ж завершено.

AGI скрипти дляAsterisk розташовуються в директорії /usr/local/share/asterisk/agi-bin/.

Чому скрипт на PHP? PHP було обрано дляAGI, т.к. callback є невід'ємною частиною проекту написаного на PHP + MySQL, тому вирішили і нехай на PHP буде. Сам скрипт:http://subnets.ru/files/callback.php.txt

Що відбувається зі скриптом?

  • визначаємо необхідні змінні
  • отримуємо дані відAsterisk `а.
  • логи, куди ж без них. У лог ми помістимо все те, що отримавAGI скрипт відAsterisk `а, це для дебага, потім можна вимкнути логування.
  • перевіряємо номер (АОН) телефонуючого на доступ доcallback
  • чи вже немає call файлу для даного номера, якщо ні, то створюємо його

Ну і залишилося справа за малим, а саме щоб був контекст (context) під номер в extensions.conf.

Допустимо нашcallback номер 84955556677 набрали з мобільного 89105647899 і йому дозволеноcallback (номер84955556677 вказаний у масиві $permit_num у скрипті), то його контекст може виглядати ось так: