Приём и обработка SMS-сообщений на Linux-машине

В одном из наших свежих проектов команде разработчиков была поставлена задача собрать максимально реальные контактные данные о пользователях нашего сайта. Жаркое обсуждение правильных и неправильных форм регистрации, одно- и двушаговые, дополнение информации по мере пользования сайтом… Казалось поток идей не остановится. Однако ни одна из них не гарантировала, что в результате мы не получим кучу никчемных данных. Валидировать? Можно, но разве все предусмотришь? Активация учетной записи через почтовый ящик для его валидации? Но куча сервисов типа 10 Minute Mail сводят на нет эффект. К тому же, специфика проекта не позволяла слишком растягивать процесс регистрации. Решено было, что пользователь должен зайти, сделать своё дело, а потом уже активировать или нет свою учетную запись. В конце концов прозвучала фраза «А давайте активировать по SMS!». Поиск провайдеров, изучение прайс-листов и отказ от идеи взвалить обработку SMS на стороннюю контору… Стало понятно, что принимать и обрабатывать их придется самим.

Скромный опыт работы с VOIP/Asterisk и подбора оборудования для VOIP-шлюза имелся. Полез по старым ссылкам к китайским братьям искать SMS-gateway. Но во-первых время поджимало, во-вторых по опыту работы с ними с первого раза редко что-то выходит, поэтому стало интересно, сможет ли обычный USB GSM-модем справиться. И, забегая вперед, скажу что это решение было правильным. По крайней мере на данном этапе.

Настройка сервера


Итак, ко мне в руки попал модемчик Huawei E1750 (HSPA USB Stick) с контрактом. Первое с чем столкнется человек взявшийся за подобную задачу, это то, что все свежие модели GSM-модемов, в угоду пользователям Windows, опознаются в системе сначала как устройство хранения данных (SCSI CD-ROM). С него запускается autorun, который установит драйвера и переключит модем в режим модема (о как!). Сразу как я узнал это, я решил «приехали». Однако еще полчаса, и была найдена утилита usb_modeswitch, которая выполняет переключение режимов модема. Только после этого модем заработает по его прямому назначению. Запускается и настраивается она просто, тут писать особо нечего.

Ну, с богом! Информации к этому моменту уже было нарыто не сказать чтоб много, но достаточно, чтобы копать в нужном направлении. Существующие решения были отфильтрованы по признаку «работает как демон», в итоге остался один кандидат — SMS Server Tools. Нужно отметить, что оригинальный пакет уже не развивается, но его продолжение SMS Server Tools 3 не только развивается, но и отлично поддерживается своим создателем Mr. Keijo «Keke» Kasvi.

К сожалению, в моей любимой Gentoo не нашлось ebuild-а для свежей версии, последняя имеющаяся версия 2.2.20. Но, недолго погуглив, я нашел уже готовый ebuild для 3-й версии, который и скомпилировал после небольшой его правки. На данный момент у меня установлена и стабильно работает версия 3.1.14.

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

Структура файла конфигурации тоже понятна до безобразия (viva unix-way!). В начале файла прописываем глобальные настройки демона, а затем в секциях описываем настройки наших устройств:
# Глобальные настройки демона
...
...

# Наш модем и его настройки
[Huawei E1750 ]
...

# И еще одно устройство, если оно у нас есть, со своими настройками
[AnotherModem]
...


Глобальные настройки

Самый важный параметр, это какие устройства демон будет опрашивать на предмет наличия новых сообщений. Если у вас всего одно устройство, как у меня, просто пропишите devices = HuaweiE1750, если их у Вас несколько, перечислите их тут через запятую.

Еще два важных параметра — это user = smsd и group = sms. Людям, знакомым с линукс, объяснять их значение не надо, я же ограничусь лишь напоминанием о правильных правах на все ресурсы, к которым демон должен иметь доступ. Ну и упомяну про такие инструкции, как pidfile = /var/run/smsd/smsd.pid, logfile = /var/log/smsd/smsd.log, значение которых тоже должно быть понятно. Кстати, на момент отладки рекомендую вставить в конфигурацию также инструкцию loglevel = 7, это позволит Вам отслеживать, что же происходит внутри демона. В дальнейшем я выставил loglevel = 5.

Настройки модема

В принципе, тут тоже, как было обещано, все просто. Однако я столкнулся с некоторыми проблемами, из-за которых я собственно и решился поделиться с Вами информацией.

Одной проблемой стало жгучее желание модема все время соскочить на новое устройство. Один раз он определялся как /dev/ttyUSB0, в другой раз под другим номером. Такое положение дел не устраивало меня. Поэтому, я стал искать как писать udev правила для устройств. Однако, когда я уже был готов внести свои изменения, обнаружилось, что ebuild usb_modeswitch уже сделал это за меня добавив в систему файл /lib64/udev/rules.d/40-usb_modeswitch.rules, согласно которому в системе появлялся симлинк на девайс по адресу /dev/gsmmodem. Его мы и пропишем в конфигурации.

Второй проблемой стало зависание модема время от времени. К сожалению, вычитывать матчасть времени уже не было, да и гугл выдал такое количество вариантов, что пробовать их все не имело смысла. Поэтому, не особо рассчитывая на помощь, я пополз на форум smstools3. Каковы же были мои удивление и радость, когда keke ответил на мой пост через жалких 2-3 часа. Нет, точного решения он не давал, однако две строки которые он рекомендовал добавить в конфиг раз и навсегда избавили меня от зависаний. Для меня до сих пор остаётся загадкой, где брать значения для них, я не нашел технической документации по модему:
check_memory_method = 1
memory_start = 0


Ну, и третьей проблемой, из-за которой затевался весь сыр-бор, стало написание обработчика SMS. Для этого в конфиг была добавлена инструкция eventhandler = /usr/local/scripts/activate, внутри которого происходила отправка на сервер проекта запроса на активацию учетной записи. Скрипт, получает два параметра — тип события и файл сообщения. Выдергивает из него нужные нам данные, и отсылает на сервер.

Итого, получили вот такой короткий конфиг:
devices = Huawei
loglevel = 5

user = smsd
group = sms
logfile = /var/log/smsd/smsd.log
infofile = /var/run/smsd/smsd.running
pidfile = /var/run/smsd/smsd.pid

alarmlevel = 7
alarmhandler = /usr/local/scripts/activate/smsd-alarm

[Huawei]
device = /dev/gsmmodem
baudrate = 115200
pin = 1111
incoming = high
cmgl_value = 0
check_memory_method = 1
memory_start = 0
eventhandler = /usr/local/scripts/activate


Неожиданный profit


Изначально форма регистрации содержала поле Мобильный телефон — это было в требованиях проекта. Пришедшее SMS должно было быть отправлено с указанного телефона, и учетная запись с этим телефоном активировалась. Однако, как оказалось, пользователи становятся в тупик, когда им в сообщении ничего не надо писать. Сначала после регистрации появилась инструкция «Отправьте на номер 12345678 сообщение с текстом «F»». Потом родилась другая, гениальная как сейчас кажется, идея: из формы было убрано поле Мобильный телефон, после короткой регистрации (Имя, Фамилия, E-mail/login, Пароль), пользователю выдается код, который он должен отправить на указанный номер. По этому коду находится учетная запись, а телефон, с которого пришла СМС-ка заносится в профиль пользователя. Вуаля, у нас есть пользователь, есть его реальный телефон, есть возможность добавить кучу телефонов в свой профиль, и сменить номер телефона в профиле в случае утери старого, отправив еще одну СМС и удалив старый номер.

Итоги


  • Практически бесплатно получили систему обработки SMS-сообщений
  • Ускорили процесс регистрации пользователей на сайте
  • Получили реальные данные о пользователе (осталось придумать как бы отсылать нам сканы паспортов)
  • Приобрели опыт, который уже хочется применить для рассылки уведомлений о каких-то событиях на серверах (отсылка в рассмотренном случае не рассматривалась, однако думаю проблем не будет)
  • Реализовали все в очень сжатые сроки (эххх, если б еще не проблема с зависаниями модема)
Поделиться публикацией

Комментарии 38

    +1
    А если клиент (5, 10 клиентов) будут упорно пытаться дозвониться на этот номер, вместо того, чтобы отправить СМС? Я к тому, что можно ли сбросить звонок скриптом? Если да, то Ваша идея просто супер!
      +1
      Поставить переадресацию, робота или вообще запретить входящие звонки.
        +2
        Думаю что можно было бы зарулить входящий вызов через Asterisk на какой-то IVR, где приятный женский голос скажет, что необходимо таки отправлять смс, а не дозваниваться. Правда не уверен как будет работать в связке с смс-шлюзом.
        • НЛО прилетело и опубликовало эту надпись здесь
            +1
            А если голос, произносящий инструкции по отправке смс, посылать звонящему как early media тем же asterisk'ом, без использования Answer(), то такой звонок будет совершенно бесплатным для звонящего. Точно работает с Мультифоном.
          +1
          Для них можно просто включить перенаправление входящих звонков на автоответчик
            +2
            Пытался дозвониться на свой модем от МТС, говорят что-то вроде «на этом номере данный сервис не поддерживается»
              +1
              если использовать 3G модем то он просто выдаст alarm в лог а человек на проводе получит что телефон вне зоны доступа… тк модемы не предназначены для передачи голоса
                0
                У меня модем от МТС сигнализирует о входящем звонке, но не реагирует на ATA комманду
                  0
                  а что пытаешься ему сказать?
              0
              Рекомендую купить сервис clickatell.com и сделать нагрузочное тестирование отправляя на свою железку смски с кликатела.
                0
                Мне думается, что для проверки было бы логичнее использовать метод отсылки через СМС на указанный номер проверочного кода, который потом надо вбить в вэб-форму. Но разумеется так расходы на связь перенесутся на ваши плечи.
                А вообще спасибо за статью, интересно. Пригодится.
                  +11
                  Я бы вообще десять раз подумал перед тем, как регистрироваться на сайте, который требует отправить куда-то смску. Где гарантия, что она мне не обойдётся рублей так в 1000?
                    0
                    Если просят отправить SMS на обычный федеральный (а не короткий) номер, то беспокоиться не о чем.
                      0
                      У МТС есть сервис, позволяющий узнать стоимость смс, достаточно отправить "?" на номер, который необходимо проверить. В ответ приходит смс от МТС со стоимостью отправки.
                      /не реклама
                        +1
                        Послал себе. Пришло "?". МТС, Москва.
                          0
                          Прошу прощения, забыл уточнить, что работает только с короткими номерами.
                      0
                      Я бы вообще десять раз подумал перед тем, как регистрироваться на сайте, который требует отправить куда-то смску. Где гарантия, что она мне не обойдётся рублей так в 1000?
                        0
                        Чёрт, случайно два раза отправил.
                      –2
                      Отличная статья!
                        0
                        > Практически бесплатно получили систему обработки SMS-сообщений
                          0
                          что-то форма глюкнула…

                          не рекламы ради, такое можно организовать совсем бесплатно, если завести учётку на littlesms.ru Можно зарегистрировать любой префикс и принимать смс через бесплатный федеральный номер. Поступающие смс можно обрабатывать как угодно — http-запрос, пересылка на емейл, смс-ответ и прочее. К тому же, такое решение гораздо эффективнее по скорости и надежнее, т.к. не используются gsm-модемы и сим-карты, номер «виртуальный».
                          0
                          check_memory_method = 1
                          memory_start = 0
                          Я знаю эти параметры, имел с ними дело при настройке kannel и помню, что очень не рекомендуется использовать память симки как промежуточное звено при приёме SMS, т.к. есть неплохая вероятность того, что симка быстро умрёт от их количества (частое и многократное перезаписывание памяти древнего стандарта). Прямой приём работает лучше, но и настраивать его геморнее, у меня получилось за неделю секса с kannel).

                          Спасибо за статью, вроде неплохой альтернативный вариант для моегоkannel, буду знать.
                            0
                            SIM-ка «умрет» не от многократного перезаписывания памяти, а от превышения лимита обращений (чтения/записи). Там на эту тему есть специальный счетчик. Делали его, если я не ошибаюсь, для борьбы с «клонами»
                            +4
                            Хорошее подробное описание, как сделать СМС сервис самому. Но, как говорится, есть ньюансы:

                            Замечание №1
                            Как сотрудник одного из крупных контент-провайдеров, удивляюсь, почему вам кто-то предлагал такое организовать за деньги. Есть подозрение, что плохо искали:)
                            Дело в том, что за прием СМС на короткий не-премиум номер (по стоимости стандартного СМС — ~1,5 руб) обычно денег не берут. Операторы в любом случае нам выплачивают копеечку даже с 1,5 руб. — поэтому, даже в бесплатном для клиента варианте, такой сервис нам, контент-провайдерам, немножко выгоден — и на перспективу развития взаимоотношений с новыми партнерами.
                            Если принципиален длинный федеральный номер — такие решения тоже предлагаются по весьма доступным ценам.

                            Замечание №2
                            С точки зрения пользователя было бы удобней не отсылать СМС, тем более на длинный номер — если провести аналогию с кликами — сколько лишних действий и нажатий кнопок придется сделать вашему пользователю. Гораздо привлекательней для авторизации отсылать СМС с кодом (как и сделано в большинстве сервисов, использующих СМС авторизацию), который будет вводится уже на сайте. Если количество пользователей у вас невелико — можно использовать тарифный план с бесплатными СМС у любого оператора.
                              0
                              Для приёма/обработки SMS можно еще Kannel использовать.
                              Я подобную схему на Kannel реализовывал, правда через два мобильника, подключенных через data-кабель и Bluetooth
                                0
                                а с помощью какого софта можно реализовать простенькую IVR через GSM-модем?
                                  0
                                  Астериск же!
                                  +4
                                  Друзья, а вы вообще в курсе, что отправить СМСку можно просто с любого номера. Вообще. Если своего SMSC под рукой нету, то вот, пожалуйста… Я не знаю насколько большие права Вы даете по входящему SMS-сообщению, но если полные — то это финиш.
                                    0
                                    А как эти сервисы вообще получили такую замечательную возможность?
                                      0
                                      В это замечательной возможности нет ничего необычного. Если у вас есть доступ к SMSC, то номер отправителя Вы можете задать любой.
                                    +1
                                    > осталось придумать как бы отсылать нам сканы паспортов

                                    Так есть же еще MMS!!!
                                      0
                                      Сорри за оффтопик, но я вот другую задачу, «секретутскую» пытался решить — софт, который «как-то» бесплатно отправляет смс по инету, без модема, хотя бы для «большой тройки». Для винды много нашёл, а для Линукса ничего. Никто не подскажет?
                                        0
                                        Я пытался сделать SMS голосование. Но у меня уже был прекрасно работающий Asterisk с двумя модемами Huawei E150. Достаточно было просто скорректировать dialplan с целью отправки сообщений на сайт. Правда столкнулся с проблемой — cURL не хочет отправлять данные из скрипта, вызываемого из дайлплана… просто возвращает ошибку 127 (не описанную в документации). А без него пока не знаю как можно заPOSTить данные на сайт. Приходится руками позже данные отправлять.
                                          0
                                          А если вызов curl запихнуть в скрипт и из астерика выполнить скрипт?
                                            0
                                            Так и есть. Если просто скрипт выполнить эмулируя параметры командной строки, то всё работает, если из дайплана вызывается, то curl выдаёт код возврата 127 и ничего не делает. Я даже формировал файл из скрипта с той командой, что не может выполниться. Даёшь файлу +x и запускаешь. Всё работает.
                                          0
                                          А скажите, зачем вам так нужны личные данные пользователей?
                                            0
                                            Ну мне они не нужны, я всего лишь исполняю капризы заказчика. Но даже если и я бы хотел знать всех посетителей моего сайта в лицо, я не стал бы обсуждать это в топике Линукс для всех

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

                                          Самое читаемое