Asterisk, автоматическое определение сотового оператора по номеру телефона даже перенесенных номеров

  • Tutorial
У Asterisk есть свой механизм для работы с базами данных, я Вам расскажу про альтернативный метод работы с базами данных из диалплана Asterisk! Его можно применить не только для работы с базами, но и с любым другим софтом на сервере. Статья про функцию «SHELL».
В документации про 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 Мегафона
На запрос:
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».

Всем спасибо)
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 19
  • 0

    Доброго дня!
    А если некоторые абоненты меняют оператора каждые 2 месяца, Ваш скрипт будет давать ложную информацию.

    • 0
      Добрый день. В том виде, что я его опубликовал, скрипт считает актуальными данными если они не старше 30 дней. Измените значение переменной lifetime на 15 или вообще на 1.
    • 0
      AEL уже не в тренде, есть lua и lua-sql для такого.
      Вызов bash скрипта с sql запросом не true-way.
      • 0
        Я процитирую Вас:
        В статье я постарался подробнее изложить суть, чтобы была возможность человеку далекому от Asterisk быстро сориентироваться в поставленной задаче
      • 0
        Если кому-то интересно про базу MNP безотносительно Asteriks, то у Мегафона есть публичный API (из плюсов — выводит еще и регион):

        www.megafon.ru/api/mfn/info?msisdn=7XXXXXXXXX
        • +1
          А Вы читали статью?
          • 0
            Читал как раз внимательно, у вас в баш-скрипте эта строчка и указана (но не уверен что до нее дочитают все). Просто сама по себе тема интересная и может иметь массу применений.
            • 0
              Вы правы, стоило поподробнее остановится на этом моменте!
              Добавил в статью.
        • 0
          Статья короткая, но тему раскрывает. Спасибо.
          • 0
            Всегда пожалуйста!
          • 0
            Спасибо. Как раз что-то подобное искал
            • +1
              Вот еще один сервис для определения оператора и наличия номера в базе mnp
              rosreestr.subnets.ru/?get=num&format=json&num=7XXXXXXXXXX
              Вообще достаточно полезен, поскольку отдает информацию о принадлежности к оператору, региону, и т.д.
              Использую для сложной маршрутизации вызовов на мобильные телефоны. Что-то через свой шлюз, что-то через местного оператора, и т.д.
              • 0
                Спасибо, вот так можно получить массив со всеми данными через этот сервис:
                array_operator_rosreestr=($(curl -s "http://rosreestr.subnets.ru/?get=num&format=xml&num=$1" | sed -e 's/<[^>]*>//gm'| sed '/^$/d'| tr -d '\t' |tr -s '\ ' '_'))
                echo ${array_operator_rosreestr[9]} # покажет нужного оператора
                echo ${array_operator_rosreestr[5]} # старого оператора
                echo ${array_operator_rosreestr[7]} # регион
                • 0
                  Любопытно — почему ID оператора и региона не бьются с мегафоновскими (для одного и того же номера)?
                • 0
                  Спасибо за сервис мегафона.
                  А не знает ли кто аналога сервиса проверки номеров HLR-запросами типа:
                  smsc.ru/testhlr
                  • 0
                    В таком сервисе самое ценное — это определение IMSI по MSISDN-у (по номеру). Не знаю как по остальным операторам, но по МТС он показывает туфту.
                  • 0
                    Посмотрел на сайт ЦНИИС (хранитель ЦБДПН).
                    Там тоже можно проверить принадлежность номера оператору (правда без региона). И это сделано очень прикольно…


                    А код можно найти вот так…


                    • 0
                      Изначально я использовал вот этот сервис: phonenum.info, но на сайте часто появляется реклама и изза этого сложно его парсить. API мегафона и rosreestr позволяют это делать гораздо проще.
                      Подобных сервисов много и с капчей и без.
                      • +1
                        Эх… и зачем я это увидел «на ночь глядя»… плод ночного бдения. Спасибо, что заглянули в содержимое страницы.

                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.