В начале этого лета в России произошли изменения в тарифах на рассылку SMS-сообщений. Правила игры изменились, цены выросли на порядок. Кто бы мог подумать, что такое может произойти с технологией, которая уже более 20 лет существует в нашей обыденной жизни. По моему мнению, «большая тройка» решила, что отправка SMS стала использоваться только в корпоративных целях (физики давно мигрировали в различные интернет-мессенджеры), следовательно, на ней можно хорошенько заработать, не боясь потерять пользовательскую симпатию. В статье представлен вариант отказа от подобных сервисов в сторону Asterisk на примере Hotspot, когда на указанный номер телефона поступает звонок и диктор сообщает пароль доступа. Тарифы отличные, расходы минимальные, работаем дальше.
▍ Введение
21 июля в курируемом мной проекте перестала работать рассылка SMS-сообщений, содержащих пароль для доступа к общедоступному Wi-Fi, организованному в интересах международной компании Coffee Cup, имеющей как собственные бары формата «кофе с собой» в разных городах, так и дилеров по всей России и в странах СНГ. Все технические подробности о том, как это было изначально сделано, можно посмотреть здесь. Для рассылки самих сообщений в силу лёгкости решения, гибкости и удобства администрирования были задействованы сторонние ресурсы, счета на которых в июле стремительно обнулились. Что, собственно говоря, произошло, стало понятно после общения с технической поддержкой:
Поддержка №1: На XXX и XXX отправка возможна только от платных имён с абонентской платой 2 000 руб./мес за каждого оператора. Если нужна временная отправка от общего имени на данных операторов в ближайшее время, есть тариф около 16 руб. за SMS на XXX и 20,30 руб. на XXX.
Или вот такой:
Я: Ищу простой способ отправки SMS, без лишних заморочек. Подойдёт любой исходящий номер.
Поддержка №2: Без регистрации и абонентской платы можно отправлять сообщения от общих имён операторов, но по повышенному тарифу (XXX: 18 руб. за SMS, XXX: 20,30 руб. за SMS). К сожалению, такая заградительная цена — ограничение, наложенное операторами.
Действительно, если поискать информацию на сайтах операторов сотовой связи, то можно увидеть примерно то же самое:
▍ Технические варианты уведомления пользователей
Называть такие тарифы заградительными весьма уместно. Пришло время искать другие решения.
Отправка SMS через собственные модемы (ведь некоторые бары оборудованы таковыми, как, например, на фото из заголовка) отпала сразу. Причины следующие:
- потенциальные проблемы и танцы с бубнами при отправке сообщений через устройства различных производителей, моделей, прошивок,
- потенциальные проблемы с зависаниями устройств,
- сложность централизованного администрирования территориально-распределённого оборудования,
- высокие риски быть заблокированными со стороны сотовых операторов, которые знают толк не только в том, как заработать, но и как вычислить таких, как мы, и ввести против нас
и не толькоразличные ограничения.
Третий вариант — это задействование возможностей открытого программного обеспечения Asterisk, когда на номер пользователя поступает автоматизированный звонок, и необходимо в качестве пароля указать последние цифры звонящего номера. Сейчас много где так организовано. Этот способ имеет преимущество — отсутствие длительности разговора, ведь после поднятия трубки АТС самостоятельно разрывает соединение. Однако имеются другие накладные расходы – необходим определённый пул арендуемых номеров (и желательно большой), который стоит денег. Например, аренда одного городского номера выходит порядка 350 рублей в месяц. Если использовать вместо арендуемых номеров обычные модемы – минусы такого решения рассмотрены выше.
Четвёртый вариант — использование Asterisk, когда на номер пользователя поступает автоматизированный звонок, и робот голосом сообщает пароль. Корпоративный арендуемый номер у компании Coffee Сup уже был, тарификация посекундная, следовательно, накладные затраты должны быть адекватными. Как это всё интегрировать в имеющуюся инфраструктуру (с учётом того, что сеть за эти годы значительно подросла), подробно рассмотрим ниже. Непосредственно общая настройка АТС к рассматриваемой теме не относится, поэтому концентрироваться на ней не будем.
▍ Hotspot с идентификацией пользователей посредством Asterisk
Изначально проект казался более сложным, чем вышел на самом деле, благодаря гибкости имеющихся решений и используемого программного обеспечения. Казалось, что нужна будет интеграция с API, например, от Google, по переводу текста в голос для работы диктора. Однако это избыточно, ведь Asterisk имеет на борту заготовленные звуковые файлы различного содержания, в том числе подходящие для нашего проекта. Общая схема следующая: пользователь подключается к Hotspot, получает приглашение на ввод номера телефона, который посредством HTTP GET передаётся на сервер АТС, где обрабатывается и формируется задание для Asterisk. Ответом на запрос является пароль доступа к Hotspot. После этого осуществляется звонок на номер пользователя, при котором проигрываются необходимые аудиозаписи с кодом доступа. Далее в рефакторинг не лезем, всё работает по старой схеме. Для начала подготовим аудиофайлы для Asterisk. Скорее всего, они не будут предустановлены:
ls /usr/share/asterisk/sounds/
apt-cache search asterisk | grep sounds-ru
apt install asterisk-core-sounds-ru asterisk-core-sounds-ru-gsm asterisk-core-sounds-ru-wav asterisk-core-sounds-ru-g722 -y
ls –l /usr/share/asterisk/sounds/ru/
В нашем проекте пароль доступа к Hotspot представляет четырёхзначное число. Здесь лежат звуки пауз, например, длительностью в 1 секунду: /usr/share/asterisk/sounds/ru/silence/1. Здесь имеются записи произношения диктором цифр: /usr/share/asterisk/sounds/ru/digits/0. Кстати, на борту представлен простой и удобный способ записи собственных сообщений. Для этого внесём изменения в имеющийся диалплан:
# nano /etc/asterisk/extensions.conf
[test-record]
exten => _1000,1,Wait(2)
exten => _1000,n,Record(/tmp/sound${EXTEN:2}:wav)
exten => _1000,n,Wait(1)
exten => _1000,n,Playback(/tmp/sound${EXTEN:2})
exten => _1000,n,Wait(2)
exten -> _1000,n,Hangup()
Укажем данный extension нужному endpoint:
# nano /etc/asterisk/pjsip.conf
[3002]
type=endpoint
context=test-record
# systemctl restart asterisk
Звоним с указанного endpoint на номер 1000, говорим что-нибудь, после чего слышим произнесённое, а качественная запись голоса будет сохранена в файле /tmp/sound00.wav. Чтобы инициировать звонок от имени АТС, можно использовать либо CLI, либо командный файл. Пример работы посредством консоли представлен ниже:
/usr/sbin/asterisk -rx "channel originate pjsip/3001/3002 application playback /var/lib/asterisk/sounds/custom/sound00"
/usr/sbin/asterisk -rx "channel originate pjsip/+71111111111@siplink-74992222222 application playback /var/lib/asterisk/sounds/custom/sound00"
Кстати, вместо проигрывания звуковых файлов может быть использовано встроенное в Asterisk приложение, которое умеет произносить цифры (для озвучивания чисел есть другое приложение) однако придётся позаниматься русификацией:
channel originate pjsip/3001/3002 application saynumber 123
В проекте вместо CLI использовался командный файл. Чтобы инициировать звонок на номер +71111111111, подготавливаем:
# nano /var/spool/asterisk/tmp/test.call
Channel: PJSIP/+71111111111@siplink-74992222222
Application: Playback
Data: /var/lib/asterisk/sounds/custom/sound00
Чтобы воспроизвести несколько файлов, их нужно перечислить через амперсанд. Копируем командный файл в нужное место, и АТС сразу выполнит полученные инструкции:
cp /var/spool/asterisk/tmp/test.call /var/spool/asterisk/outgoing/test.call
Приведу пример используемого extension:
# nano /etc/asterisk/extensions.conf
[siplink-out-74992222222]
exten => _XXXX,1,Dial(PJSIP/${EXTEN})
exten => _+X.,1,Dial(PJSIP/${FILTER(+0-9,${EXTEN})}@siplink-74992222222)
Здесь хочу порекомендовать провайдера IP-телефонии Siplink — профессиональные ребята. Давно пользуюсь их услугами, приятно работать: хорошая поддержка, адекватные тарифы.
На этом настройка Asterisk заканчивается, осталось доработать веб-сервер и RouterOS. В скрипте для работы Hotspot удалим использование API сторонних сервисов и добавим следующее:
:local SITE pbx.tratata.ru;
:local PORT 443;
:local APIKEY 0123456789;
…
local pass ([/tool fetch url="https://$SITE:$PORT/\?secret=$APIKEY&msisdn=$uname" output=user as-value]->"data")
Пароль пользователя и командный файл для Asterisk будем генерировать прямо на АТС. Для этого настроим любой веб-сервер, активируем HTTPS. Как это сделать, упускаем, инструкций более чем достаточно. Подготовим index.php:
<?php
$api = '0123456789';
$key_from_get = trim(htmlspecialchars($_GET["secret"]));
$dir = '/usr/share/asterisk/sounds/ru';
$silence = "$dir/silence/1";
$sip1 = "@siplink-74992222222";
$sip2 = trim(htmlspecialchars($_GET["msisdn"]));
$fileWeb = 'file.txt';
$fileAsterisk = 'file2.txt';
if ( $key_from_get === $api AND strlen("$sip2") === 10 AND ctype_digit("$sip2") ) {
$pas1d = random_int(0, 9);
$pas2d = random_int(0, 9);
$pas3d = random_int(0, 9);
$pas4d = random_int(0, 9);
echo "$pas1d$pas2d$pas3d$pas4d";
$myfile = fopen("$fileWeb", "w");
$txt = "Channel: PJSIP/+7$sip2$sip1\n";
fwrite($myfile, $txt);
$txt = "Application: Playback\n";
fwrite($myfile, $txt);
$txt = "Data: $silence&$dir/digits/$pas1d&$silence&$dir/digits/$pas2d&$silence&$dir/digits/$pas3d&$silence&$dir/digits/$pas4d\n";
fwrite($myfile, $txt);
fclose($myfile);
rename("$fileWeb", "$fileAsterisk");
}
?>
Веб-сервер получает номер пользователя, генерирует ему пароль доступа, возвращает его в качестве ответа и подготавливает соответствующее задание для АТС. Непосредственный перенос файла в папку Asterisk выполняет bash-скрипт. Такая прослойка сделана для возможности прикручивания допов на будущее, работает стабильно. PHP-cкрипт валидирует и проверяет длину и состав номера пользователя, при звонке сам подставляет телефонный код +7, чтобы отсутствовала возможность списывать деньги со счёта посредством звонков, например, на Марс. Здесь необходимо отметить, что используемый скрипт RouterOS содержит проверку и блокировку множественных однотипных запросов:
#Cheks user from spam
:local sendtest yes;
:foreach i in=[/ip firewall address-list print as-value where list=spam_cheks_list] do={
:if (($i->"address")=$uname) do={
:set $sendtest no;
}
}
:if ($sendtest=yes) do={
/ip firewall address-list add list=spam_cheks_list address=$uname timeout=00:05:00;
…
}
JavaScript на странице Hotspot никакой реальной защиты не добавляет, а только помогает пользователю не ошибиться при наборе цифр. На страницу добавлено уведомление о том, что поступит звонок от робота с арендуемого нами корпоративного номера:
Готово! Получаем приятную стоимость одного такого звонка в 20-30 копеек, что даже дешевле, чем отправка SMS по «старым» доиюльским ценам:
▍ Заключение
В статье мы рассмотрели доработку Hotspot до идентификации пользователей посредством звонка от Asterisk и диктовки пароля с целью миграции от SMS-gateway-шлюзов из-за значительного удорожания их сервисов. Минусом такой организации является то, что на время приёма звонка сотовый телефон посетителя отключается от Wi-Fi, что не такая уж и проблема, так как при повторном подключении имеется возможность выбрать «У меня уже есть код». Решение рабочее, следующая точка отказа – борьба большой тройки с IP-телефонией, как уже некоторые начинают делать, безразборчиво блокируя подобные входящие вызовы, ссылаясь на противодействие мошенничеству. Как видно из кода, несложно всё доработать на использование пула номеров и идентификацию посредством ввода последних цифр звонящего номера, без длительности разговора и списания денег. Полученное решение достаточно гибкое, много что можно нарастить. Моё личное мнение: Open-source Software — сила, особенно в очумелых руках.
Telegram-канал с полезностями и уютный чат
Комментарии (40)
khegay
17.11.2022 12:49+1А можно было бы сделать в другую сторону: при подключении, показывается короткий код: 123. Дальше, пользователю поступает звонок и нужно ввести этот код.
Stanislavvv
17.11.2022 13:46+1Это сложнее и, вероятно, дороже... Одно дело получить из формочки циферки и пнуть в базу, другое - настраивать свой сервер с астериском, где потом настраивать распознавание циферок, посылание их в сервис (опять же свой) с номером телефона, который и пошлёт в базу.
К тому же, человек может тупить при звонке дольше, чем слушать цифры, что опять же сказывается на стоимости.
olegtsss Автор
17.11.2022 16:17+2Проиграем с длительностью разговора. Так она у нас условно фиксирована (10 секунд примерно), а так придется ставить таймер секунд на 30. Ну и соответственно - это будет дороже.
TimsTims
17.11.2022 22:50Ужасная идея. Наверное самая худшая). Самая простая user-friendly: Попросить пользователя самому сделать прозвон по нужному номеру.
Плюсы: Не нужно совершать вызов на "левый" номер, если пользователь в нём ошибся. Не нужно пользователю запоминать пин код. Не нужно тратиться на смс. Не нужно тратиться на исходящий вызов.
olegtsss Автор
18.11.2022 03:40О каком user-friendly вы пишите? "Попросить пользователя самому сделать прозвон по нужному номеру" -> это как раз наоборот, не user-friendly:
1) страх, что вызов стоит денег
2) убийство корпоративного номера для приема рабочих звонковTimsTims
18.11.2022 10:47страх, что вызов стоит денег
Говорим, что вызов бесплатный.
корпоративного номера для приема рабочих звонков
Корпоративный номер не относится к проблеме "user-friendly", но тем не менее, не обязательно ведь использовать телефон приёмной. Можно отдельную сим-карту купить, и только смотреть входящие вызовы, все вызовы сбрасывать.
О каком user-friendly вы пишите
О самом лучшем варианте из возможных, в условиях низких ресурсов и необходимости в идентификации.
sdnv
18.11.2022 14:07Хм, идея
Можно взять номер 8-800-*
Но опять же - непонятно как к этому отнесутся юзеры. Звонить еще кому-то...
aax
17.11.2022 12:49+2На мой взгляд, по меньшей мере на перспективу, нужно не искать новые "костыли"(и понятно что временные), а решать проблему в корне, т.е. добиваться отмены законодательных требований на авторизацию в публичном хот-споте. Тем более, что и "товарищ майор" понимает, что таким способом серьезных людей, если что не вычислить. А вот неудобства и физические и этического плана налицо для большинства людей.
miarh
17.11.2022 12:57+2Не реально. Кто добиваться то будет? Голос малого бизнеса и по более важным вопросам не слышат, а для крупного бизнеса - это не затраты. Про фан ид уже кто только не сказал, и люди на стадионы не ходят - но пятиться назад нпша система не может.
Для себя решаю договором с провайдером. Деньги не большие, но зато рисков нет - вот к ним идите.
selivanov_pavel
17.11.2022 13:02+2Плохо, что теперь система стала недоступна слабослышащим и не владеющим русским языком пользователям.
RekGRpth
17.11.2022 13:31+2дак можно же сделать вообще без смс и звонков (положительной длительностью): пользователь вводит свой номер телефона и отправляет форму, а потом сам звонит на указанный провайдером номер телефона, где ему в предответе (т.е. фактически трубка не снята) провайдер отвечает, что услуга активирована
olegtsss Автор
17.11.2022 16:23+1Я бы не сам не звонил. Не понятно, сколько стоит звонок, может очень дорого, специально обманывают. Другое дело принять входящий вызов. И у нас по ТЗ в аренде один городской корпоративный номер, он и раздает всем коды.
vassabi
17.11.2022 21:18а может в обратную сторону сделать - вводите свой номер на сайте, потом вам звонят и сразу сбрасывают, а на сайте просят ввести последние 3-4 цифры набравшего вас номера ? (а арендовать 5-10 номеров вместо 1000, чтобы возможность угадать была небольшой. 100 номеров - если в кафе ходят студенты)
olegtsss Автор
18.11.2022 03:46+1Так можно, там в коде не много что поправить надо. Только заранее нужно посчитать экономику. Аренда 5 номеров - это 2500 р. в месяц (хотя 5 - это очень мало, так как угадать не составит труда, зная хотя бы один, можно просто перечислять свой номер, типа +71111111111, +71111111112 ... и раз за разом вводить известный номер, попадете в точку менее, чем за минуту). 2500 р это 8000 регистраций на Hotspot.
Ainvain
19.11.2022 13:54Я думал, что для такого способа авторизации используют сторонние сервисы, у которых тысячи номеров. Кинул запрос на API, получил последние цифры номера, который позвонит клиенту, сравнил с вводом клиента. Теоретически для такого сервиса стоимость одного запроса может быть очень низкой. По первым ссылкам в гугле максимум 20 копеек за звонок.
olegtsss Автор
19.11.2022 15:34Дополнительная точка отказа при приблизительно равных финансовых затратах.
Stanislavvv
17.11.2022 13:47+1Лучше сделать, чтоб требовалось ввести последние цифры номера, с которого звонили. Глухим точно поможет.
olegtsss Автор
17.11.2022 16:25Об этом я писал в статье. Минус такого решения - нужен пул номеров. Аренда каждого стоит денег. А так там минимальные изменения по коду будут.
kik_krsk
17.11.2022 18:33Можно сделать окно с вводом номера клиента, а потом его попросить позвонить по номеру и сбросить. При звонке закончить авторизацию на стороне астериска
olegtsss Автор
17.11.2022 18:40+1Пользователь должен совершить вызов. И его сомнения, платно ли это. И номер по ТЗ является общим корпоративным, на который звонят по разным вопросам.
FlashHaos
18.11.2022 10:04+1Спасибо, я хоть наконец понял, почему от удобных смс все переходят на эти раздражающие звонки.
Вообще, конечно, удивительно - асинхронная операция с передачей фиксированного и небольшого пакета данных стоит дороже, чем более сложный (на взгляд дилетанта) звонок.
serafims
18.11.2022 14:07Ну ту скорее цена исходит из того, что СМС - это, получается, как телеграмма в почтовом мире. Быстро, имеет, хоть и минимальную, юридическую значимость, но при этом цена не соизмерима с объемом информации (весом посылки).
olegtsss Автор
18.11.2022 15:37Я думаю, что операторы либо таким образом прикрутили себе дополнительный способ зарабатывать на юридических лицах, не опасаясь за "физическую" клиенто-ориентированность. Либо уже так накладно стало содержать и обслуживать оборудование SMS шлюзов.
vviz
18.11.2022 22:06А вот такая мысль - во многих кафе есть информационные мониторы - клиент вводит в форме номер телефона и на монитор выводится последние четыре цифры номера и пинкод доступа.
olegtsss Автор
19.11.2022 08:08Так вы не подтвердите, что номер телефона принадлежит гостю, как требует регулятор.
Seganda
19.11.2022 08:08Молодец изобрел велосипед, которому 10 лет)
Не знаю как вы, а я давно использую вообще бесплатный вариант (практически) сам клиент делает гудок на номер с которого его сразу же скидывает, после чего происходит его регистрация в рейд сервере с окном авторизации в 3 минуты (за столько он должен авторизоваться после гудка, либо делать новый гудок)
Все. Затрат нет. Возможных проблем с недозвоном итд тоже нет.
progchip666
Осталось дождаться когда наконец вырастут тарифы на распространение Телефонного Спама, который уже превзошёл не только все разумные, но и неразумные пределы.
olegtsss Автор
Мигрируют в мессенджеры!