Pull to refresh
70.27
Слёрм
Учебный центр для тех, кто работает в IT

Определение региона по номеру телефона в Asterisk без использования БД

Reading time 4 min
Views 10K


Для многих компаний, работающих по всей стране, бывает очень важно знать, из какого региона именно поступил каждый входящий звонок, например, для оценки эффективности маркетинговой кампании по интересующим регионам. Конечно, можно заставить операторов call-центра уточнять эту информацию у звонящего каждый раз, но все же удобнее получать такую информацию в автоматическом режиме.
Кроме того, при осуществлении исходящих вызовов бывает важно звонить именно с номера того региона, где находится клиент. Можно, конечно, составить исходящие маршруты, но при количестве регионов более трех, да еще и с учетом мобильных номеров, конструкция получается монструозной.

Конечно, для реализации подобной задачи можно использовать базу данных, и статьи с реализацией с использованием MySQL можно найти в том числе и на хабре, но иногда использование БД неуместно или невозможно. Поэтому ниже вы найдете пример простой реализации требуемого функционала без использования баз данных, а именно простой скрипт и небольшой кусок диалплана для Asterisk, с помощью которых мы получим интересующую информацию.

По адресу www.rossvyaz.ru/activity/num_resurs/registerNum находится официальная, обновляемая “Выписка из реестра Российской системы и плана нумерации” в четырех томах, по первым цифрам кода: 3, 4, 8 и 9. Нам нужно скачать все файлы в формате csv, объединить их, удалить ненужные и пустые поля, поменять кодировку на UTF-8, и все пробелы заменить на "_", чтобы потом было проще работать в bash-скрипте.

Файл получается следующего вида:

префикс! начальный номер! конечный номер! кому принадлежит! где зарегистрирован

999!9440000!9449999!"ОАО_""Основа_Телеком"""!Ставропольский_край
999!9450000!9459999!"ОАО_""Основа_Телеком"""!Тверская_область
999!9460000!9469999!"ОАО_""Основа_Телеком"""!Тульская_область
999!9470000!9479999!"ОАО_""Основа_Телеком"""!Ульяновская_область
999!9480000!9489999!"ОАО_""Основа_Телеком"""!Ярославская_область
999!9490000!9499999!"ПАО_""МегаФон"""!Республика_Саха_/Якутия/


Теперь напишем bash скрипт. Сначала отберем строки по трехзначному коду, потому что прогонять каждый раз весь файл через цикл очень долго. У меня на тесте один прогон длился 4 секунды, а текущий вариант выполняется гораздо быстрее, хотя тоже не моментально

#!/bin/bash

#Определим переменные
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"  #определим директорию со скриптом
FILE=9.csv   #имя файла
NUM=$1       # номер, переданный скрипту в 10-значном формате
PREF=${NUM:0:3} #код
MID=${NUM:3:11} # сам номер
lines="$( cat $DIR/$FILE | grep ^$PREF )"   # получаем из файла все вхождения по коду города. Все строки 
#слепляются тут в одну очень длинную строку, именно поэтому и нужно было избавиться от пробелов, которые теперь будут отделять записи друг от друга

for str in $lines; #цикл по всем вхождениям
do 

start=$( echo $str | cut -d '!' -f2 )   #получаем начальный и конечный номера диапазона
stop=$( echo $str | cut -d '!' -f3 )

if [ "$MID" -le "$stop" ]&&[ "$MID" -ge  "$start" ] #если наш номер входит в диапазон
then
reg=$( echo $str | cut -d '!' -f5 )    #получаем название региона
break  #выходим из цикла
fi

done
echo -n $reg # и выводим результат
exit 0


Обратите внимание на параметр -n в вызове echo. Он необходим, так как без него результат выполнения скрипта помимо названия региона будет содержать перевод строки, что нам совсем ни к чему.

Теперь нужно дать права скрипту на выполнение
chmod +x region.sh


и не забыть дать доступ тому пользователю, от которого работает Asterisk к скрипту и файлу с данными.

chown asterisk:asterisk -R /path-to-script


Для проверки запустим свой скрипт с каким-нибудь номером из консоли и убедимся в его работоспособности.

Остается работа с Asterisk. Приложение System, которое обычно используют для исполнения скриптов, нам не подходит — нам нужен результат работы скрипта, а не статус выполнения!

Поэтому воспользуемся функцией SHELL:

exten => 9999,n,Noop(${CALLERID(num)})
exten => 9999,n,Set(num=${CALLERID(num):1})  ; номера у нас 11-значные, так что первую цифру отрежем

exten => 9999,n,Set(__reg=${SHELL(/home/asterisk/region.sh ${num}  )})
exten => 9999,n,Noop(${reg})


Обратите внимание, переменную мы присваиваем с двумя символами "__" в начале, чтобы она наследовалась при переводе звонка по Goto в другие контексты и макросы.

В консоли в момент звонка мы соответственно увидим

Executing [9999@region] NoOp("SIP/123-00000026", "79063454647") in new stack
    -- Executing [9999@region] Set("SIP/123-00000026", "num=9063454647") in new stack
    -- Executing [9999@region] Set("SIP/123-00000026", "reg=Самарская_обл.") in new stack
    -- Executing [9999@region] NoOp("SIP/123-00000026", "Самарская_обл.") in new stack


Аналогичным образом можно получить название оператора связи по каждому номеру, только поле в скрипте нужно будет получить не под номером 5, а под номером 4
	reg=$( echo $str | cut -d '!' -f4 )


Конечно, такое решение мы бы не рекомендовали использовать на высоконагруженных системах из-за достаточно длительного выполнения самого скрипта, однако в ряде случаев оно может быть очень полезно.

Автор статьи: системный администратор Centos-admin.ru — Алексей Дмитриев.
Tags:
Hubs:
+10
Comments 14
Comments Comments 14

Articles

Information

Website
slurm.io
Registered
Founded
Employees
51–100 employees
Location
Россия
Representative
Антон Скобин