У Asterisk есть свой механизм для работы с базами данных, я Вам расскажу про альтернативный метод работы с базами данных из диалплана Asterisk! Его можно применить не только для работы с базами, но и с любым другим софтом на сервере. Статья про функцию «SHELL».
В документации про SHELL написано:
В отличии от SYSTEM, SHELL возвращает результат выполнения команды. А в отличии от func_odbc.conf, всю логику обработки результатов запроса к базе данных можно вынести из диалплана Asterisk. С помощью SHELL и bash можно горы свернуть, при этот диалплан можно оставить практически без изменений. Кстати я его пишу на AEL(отличная статья про AEL).
Я в скрипт передаю внутренний номер звонящего, просто так, этот номер добавляется в базу.
И сам скрипт на BASH, он делает запрос в базу для поиска старых записей, добавляет новые в базу и спрашивает у мегафона, у какого оператора сейчас находится номер.
В конце закомментирована строчка с альтернативным сервисом запроса, кто хочет, может допилить его как резервный канал.
Дамп базы «operators».
Всем спасибо)
В документации про SHELL написано:
SHELL(command)
Runs command and returns its output
В отличии от SYSTEM, SHELL возвращает результат выполнения команды. А в отличии от func_odbc.conf, всю логику обработки результатов запроса к базе данных можно вынести из диалплана Asterisk. С помощью SHELL и bash можно горы свернуть, при этот диалплан можно оставить практически без изменений. Кстати я его пишу на AEL(отличная статья про AEL).
Контекст обработки звонков на мобильные номера
context outgoing_calls_mobile { _89XXXXXXXXX => { Noop( file_conf outgoing_calls.ael context outcoming_calls_mobile); Noop(Звонок от ${CALLERID(num)} на номер ${EXTEN}); Set(mobile_operator_info=${SHELL(/etc/asterisk/scripts/operatorIF.sh ${EXTEN:1} ${CALLERID(num)})}); // Проверим нет ли ошибки в запросе если есть, уйдем в контекст "error" if ("${mobile_operator_trunk_cid}" = "ERROR") { Gosub(error,s,1(${CALLERID(num)},${EXTEN})); }; // Воспользоватся функцией CUT, в качестве разделителя у нас запятые Set(mobile_operator_name=${CUT(mobile_operator_info,\,,1)}); Set(mobile_operator_id_region=${CUT(mobile_operator_info,\,,2)}); Set(mobile_operator_region=${CUT(mobile_operator_info,\,,3)}); Set(mobile_operator_region_id=${CUT(mobile_operator_info,\,,4)}); // У нас есть четыре переменные: // mobile_operator_name - Имя оператора // mobile_operator_id_region - id оператора // mobile_operator_region - регион оператора // mobile_operator_region_id - id - региона оператора // У вас должны быть сопоставлены имена операторов с транками, у себя я делаю отдельный // // запрос в базу для этого сопоставления, здесь же предположим, что имена сопоставлены. Dial(SIP/${mobile_operator_name}/${EXTEN:1},60,); // Проверка статуса звонка Gosub(test_dial,s,1(${DIALSTATUS},${exten})); Hangup(); }; };
Я в скрипт передаю внутренний номер звонящего, просто так, этот номер добавляется в базу.
И сам скрипт на BASH, он делает запрос в базу для поиска старых записей, добавляет новые в базу и спрашивает у мегафона, у какого оператора сейчас находится номер.
Подробнее про API Мегафона
Скрипт использует запрос к публичному API Мегафона
На запрос:
API возвращает строчку вида:
На запрос:
http://www.megafon.ru/api/mfn/info?msisdn=79XXXXXXXXX
API возвращает строчку вида:
{"operator":"Билайн","operator_id":99,"region":"Новосибирская обл.","region_id":56}
В конце закомментирована строчка с альтернативным сервисом запроса, кто хочет, может допилить его как резервный канал.
вот он bash скрипт
#!/bin/bash sql='mysql -uprovisioning -pxkYyNFuyc3nEKsFj -Dasterisk -e' # Имя базы данных, имя пользователя и пароль для доступа к базе данных lifetime=30 # срок в днях, после которого запись в базе данных считается устаревшей # Поищем записи в базе данных, которые не старше 30 дней, не стоит лишний раз беспокоить чужой сайт. array_operator_old=($($sql "SELECT operator,operator_id,region,region_id FROM operators WHERE to_phon_nomber like '$1' \ and data >DATE_ADD(NOW(), INTERVAL -$lifetime DAY) limit 1"| awk 'NR>1')) # Проверим не пустой ли ответ от базы, если не пустой, то выведем данные и выйдем из скрипта. if [ -n "${array_operator_old[1]}" ] then operator_old=${array_operator_old[0]} operator_id_old=${array_operator_old[1]} region_old=${array_operator_old[2]} region_id_old=${array_operator_old[3]} echo -n $operator_old,$operator_id_old,$region_old,$region_id_old exit 0 fi # Если в базе не нашли запись, то делаем запрос на сайт: array_operator=($(curl -s http://www.megafon.ru/api/mfn/info?msisdn=$1|tr -d '"{}'|tr -s ' ' '_'|tr -s ',' '\t')) # Проверка на ошибку, если есть ошибка, то крикнем ERROR и выйдем из скрипта test_error=$(echo -n ${array_operator[@]}|grep error) if [ -n "$(echo -n ${array_operator[@]}|grep error)" ]; then echo -n ERROR; exit 0; fi # Если ошибки нет, то выводим данные и добавляем/обновляем запись в базе # Формируем переменные и выводим их через запятую. operator=$(echo -n ${array_operator[0]} | tr -d 'operator:'|tr -d '\,') operator_id=$(echo -n ${array_operator[1]} | tr -d 'operator_id:') region=$(echo -n ${array_operator[2]} | tr -d 'region:') region_id=$(echo -n ${array_operator[3]} | tr -d 'region_id:') $sql "REPLACE INTO operators\ (id, data, to_phon_nomber, operator, operator_id, region, region_id, in_phon_nomber)\ VALUES\ (NULL,\ NULL,\ '$1',\ '$operator',\ '$operator_id',\ '$region_old',\ '$region_id',\ '$2')" #operator=$(curl -s https://phonenum.info/phone/$1|grep Оператор\:|head -n1| sed 's/Оператор\:\ //'|tr -s "[:space:]" "_"|sed -r 's/\..*//') echo -n $operator,$operator_id,$region,$region_id exit 0
Дамп базы «operators».
Всем спасибо)
