Настройка SMS-шлюза Kannel

  • Tutorial
Несколько раз были упоминания такого замечательного софта как kannel, однако почему-то нет конкретных описаний примеров его интеграции. Здесь приводится пример сервиса, который можно реализовать при договоренности с оператором сотовой связи (опсосом), однако до сих пор не понятно каким образом это сделать. Попробую исправить эту ситуацию.

Оффтопик. Зачем это мне понадобилось?


Я давно работаю над одним проектом, суть которого заключается в проведении реальных городских игр под флагом Мегафона. Сначала это были игры, для которых был создан простенький онлайн-сервис на Zend Framework, в котором можно было регистрироваться, формировать команды, участвовать в играх, получать задания, вводить ответы. Однако, мы с организаторами задумались, каким образом этот процесс можно было бы сделать более доступным для масс и более мобильным. Решили переделать данную платформу для работы с SMS. Сказано – сделано, я связался с технарями Мегафона, узнал каким образом мы могли бы принимать и отправлять SMS (естественно, значительно более предпочтительно было использовать http, т.к. никаких усилий для его интеграции не требовалось и многие sms-сервисы предоставляют такую возможность), в Мегафоне дали лишь голый SMPP. Делать нечего, пришлось выкручиваться.

Долго искал хороший вариант для шлюза, таким вариантом стал Kannel — опенсорсный SMS, WAP шлюз. WAP-составляющая меня не интересовала, однако он оказался действительно очень качественным решением для SMPP-HTTP шлюза (так же его можно использовать для отправки и приема SMS с помощью SMPP в качестве сервера, MySQL для приема и отправки сообщений в виде строк БД).

Перейдем к практике.


Во многом конфиги дублируют то что я приводил в своей статье про интеграцию с Мультифоном, однако здесь именно приводится пример работы с SMPP оператора сотовой связи.

Я пропущу часть установки и первичной настройки, вы с ними можете ознакомиться в ранее упомянутой статье.

Немного теории. Эта система немного нестандартна. Она состоит из нескольких отдельно стоящих демонов. Есть демон, который надзирает над остальными, и, если вдруг процесс умирает, то он его запускает заново. Этот демон прописан при запуске из rc.d или init.d, можете в пусковых скриптах ознакомиться с его параметрами.

bearerbox – главный демон, который держит связь по SMPP в качестве клиента, работает с 3g-донглами, слушает порт для подключения других демонов.
smsbox – демон, отвечающий за прием сообщений из веб-сервиса и передающий их в bearerbox для отправки
opensmppbox – демон, который работает как SMPP сервер для подключения других клиентов. Тоже подключается к bearerbox и работает через него.
wapbox – демон, работающий как wap-гейт. Честно говоря, я толком не разбирался с ним.
sqlbox – отличный интересный демон, который может записывать приходящие сообщения в MySQL БД определенной структуры, а так же отправлять SMS, которые добавляются в MySQL БД. Это дает возможность интегрировать sms непосредственно в модель по MVC. То есть, отправка — это всего лишь создание и сохранение объекта sms внутри вашего MVC приложения, круто, да? И аналогично приём, однако, в таком случае вы не получите callback о том что у вас пришло sms, придется запускать скрипт по крону и это уже будет не realtime.
За каждым из этих демонов должен быть привязан свой run_kannel_box. Это демон-надзиратель, для которого нужно дополнительно прописать в стартовые сценарии, если вы хотите в вашей конфигурации запустить больше одного bearerbox/smsbox/wapbox или присоединить другие демоны. Либо написать собственные сценарии с использованием параметра командной строки --parachute (-P), как предложил в комментариях zerkms.

Конфиг с комментариями

group = core
admin-port = 13000 #порт, на котором вы сможете проверить состояние подключений и производить некоторые сервисные действия
admin-password = pass  #админ-пароль, никогда им не пользовался (т.к. всегда через консоль перезапускаю)
log-file = "/var/log/kannel/bearerbox.log"
log-level = 1 #если будут глюки, то устанавливайте в 0. 1 чтобы не превращать логи в помойку.
access-log = "/var/log/kannel/access_kannel.log"
store-file = "/var/log/kannel/store_sms"
smsbox-port = 13001  #порт, к которому будут подключаться смс-боксы
dlr-storage = internal
sms-resend-retry = 1  #всего 1 попытка при отправке.

group = smsc
smsc-id = povoljye
smsc = smpp
host = xxx.xxx.xxx.xxx  #параметры, которые получаем у ОПСОСА
port = xxxx
smsc-username = "name"
smsc-password = "pass"
source-addr-ton = 0  #эти 4 параметра вы должны получить у ОПСОСА. Без них ничего не будет работать.
source-addr-npi = 1  #в данном случае - параметры Мегафона.
dest-addr-ton = 1
dest-addr-npi = 1
system-type = VMA  #по-моему ни на что не влияет)
throughput = 1000  #макс. пропускная способность
reconnect-delay = 5  #переподключение после дисконнекта
connection-timeout = 120  #считать разрывом, если другая сторона не отвечает в течение N сек.
transceiver-mode = true  #Внимание, обязательно указывайте этот параметр! Вызывает дикие неуловимые глюки, если вы будете использовать единый порт для приема-передачи без этого параметра. Мне пришлось писать главному коммитеру данного ПО, чтобы найти этот косяк, не повторяйте моих ошибок.
denied-smsc-id = kemerovo #в данном случае - необходимо для того чтобы разграничить куда будут идти SMS при явном указании SMSC. Иначе SMS будут уходить round-robin, что будет нежелательно, если ваши центры неравнозначны, не могут отправлять SMS одним и тем же номерам.
allowed-smsc-id = povoljye
preferred-smsc-id = povoljye

group = smsc  #пример сочетания двух smsc для одного приложения. В данном случае - один для поволжья, а другой для сибири.
smsc-id = kemerovo
smsc = smpp
host = xxx.xxx.xxx.xxx  #все аналогично
port = xxxx
receive-port = xxxx
smsc-username = "kemerovo"
smsc-password = "pass"
source-addr-ton = 0
source-addr-npi = 1
dest-addr-ton = 1
dest-addr-npi = 1
reconnect-delay = 5
system-type = VMA
throughput = 1000
connection-timeout = 120
transceiver-mode = true
denied-smsc-id = povoljye
allowed-smsc-id = kemerovo
preferred-smsc-id = kemerovo

group = smsbox
bearerbox-host = localhost
sendsms-port = 13003  #порт, на котором smsbox слушает http для отправки сообщений
global-sender = 000037  #номер телефона отправителя по умолчанию
log-file = /var/log/kannel/smsbox.log
log-level = 0
access-log = /var/log/kannel/access_smsbox.log

group = sendsms-user
username = "user1"  #пользователь, которого вы должны указывать при отправке SMS в вашем http запросе
password = "pass"
concatenation = true #включить склейку сообщений
max-messages = 20 #максимальное число склеенных сообщений
default-smsc = povoljye

group = sendsms-user
username = "user2"
password = "pass"
concatenation = true
max-messages = 20
default-smsc = kemerovo

#ENGINE
group = sms-service
keyword = default #любые sms будут приходить сюда. Можно их отделить с помощью ключевого слова.
post-url = "http://example.com:8080/controller/action/tel/%p/time/%t/coding/%c/smsc/%i" #зендовский url с параметрами
concatenation = true
max-messages = 0  #по умолчанию kannel отправляет ответ, который приходит в теле http response. Мне это не надо, т.к. я предпочитаю управлять исходящими сообщениями из приложения.


Итак, в данном случае мы рассмотрели подключение к 2м sms-центрам Мегафона с раздельной отправкой в зависимости от параметра smsc.

Так мы отправляем SMS (см. предыдущий пост на счет проблем с кодировками)
http://example.com:13003/cgi-bin/sendsms?smsc=$smsc&username=user1&password=pass&coding=2&to=79277777777&text=some_text


А так получаем текст SMS в нашем скрипте (на примере PHP), в данном случае он передается в теле POST запроса.
$msg = file_get_contents('php://input');


Опять таки, при наличии фаервола – необходимо открыть соответствующие порты при обращении снаружи или при работе изнутри открыть loopback.

Из ссылок опять привожу юзергайд, т.к. он весьма исчерпывающий. Для испытывающих проблемы с подключением – пишите в комменты или в dev mailing list, там помогут.
Поделиться публикацией
Похожие публикации
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 26
  • +3
    Вы не описали самый интересный вопрос, как пробиться через первые линии техподдержки мегафона к технарям и сколько стоит доступ к провайдерскому SMPP.

    Расскажете?
    • 0
      Тут я не могу вас обрадовать тем что это так просто.
      Это PR-проект Мегафона, которому предшествовали долгие годы сотрудничества организаторов и местного филиала Мегафон.
      Поэтому я не знаю сколько бы стоило подключение и выделение короткого номера, но я думаю, что у всего есть своя цена.
      • +1
        У каждого из операторов свои цены на вход в контент-провайдерский бизнес.
        Но они не столь высоки, как может показаться на первый взгляд
      • 0
        Контакты технарей в процессе тестирования дадут.
        Да, у каждого из четверки раньше были свои особенности реализации smpp.
        • 0
          Не сочтите за рекламу, но есть такая фирмочка как citinet mobile. Ценники у них вполне адекватные и проблем с технарями нет :)
          • 0
            Да достаточно много реселлеров с низкими ценами и с ними можно вполне адекватно работать на первом этапе, чтобы не связываться с каждым опсосом в отдельности. Я знаю фирмы, которые работают по 8коп/смс с подменой номера при достаточно больших объемах. В случае небольших объемов или тестирования можно банально купить 3g-донгл и отправлять-принимать через него (тарифы в лучшем случае 11-20 коп/sms в зависимости от оператора). Такой случай как раз описан в предыдущей статье.
          • +1
            Попробую я рассказать) В свое время просто заполнил на сайте Мегафона форму обратной связи. Перезвонили через 2-3 суток. Услуга тогда называлась «ИнтраЛинк», актуальна или нет сейчас у них такая — не в курсе.
          • 0
            Году в 2009, писали на PHP подключение через SMPP к операторам большой тройки.
            Мало того что сами версии SMPP были разные и реализованы не в полном соответствии с протоколом, так еще были отличия не отраженные даже во внутренней документации.
            Приятно слышать что сейчас все проще.
            • +1
              kannel действительно, очень полезная и хорошо продуманная штука. Используем уже два года
              • 0
                sqlbox упомянули. Однако же не показали как с ним работать.
                Зато привели рассово неверный store-file = "/var/log/kannel/store_sms", при котором прошедший через вас смс-трафик не хранится, и не всегда получается получить корректный отчет провайдера о доставке (ибо отчет то пришел, а kannel к тому времени ничего не знает об этой смски, т.к. она стерта из store-file).
                • 0
                  И да, с трудом верится что мегафоновский SMPP-сервер пропускал трафик без указания вами в конфиге kannel параметров bind-addr-ton и bind-addr-npi.
                  • 0
                    Я не пользуюсь sqlbox, это нестандартное средства, но пробовал и, если интересно, могу привести конфиги для этого.
                    DST не используется в данной системе. И безусловно в случае когда нужно хранить DST и обеспечивать более надежный прием/доставку, то можно осуществлять хранение временной информации в MySQL.
                    Я использую именно те параметры, которые указаны. Те параметры, которые вы привели являются необязательными и не нужны в данном случае, по умолчанию равны 0.
                  • 0
                    А как правильно?
                    sqlbox, если я правильно понимаю, умеет хранить только DLR.
                    У меня, например, пока не получилось настроить его аналогично store-file.
                    Единственное, что я нашёл — это запуск внешней команды для сохранения СМС в БД, но kannel дальше с этой информацией работать не будет.
                  • 0
                    SMPP-сервер «Мегафон-Кавказ» с вами в корне не согласен :)
                    • 0
                      Выйдем на Кавказ – будем настраивать для Кавказа. Эти специфичные для конкретных SMPP серверов параметры стоит настойчиво требовать от технарей по ту сторону баррикад, а не выдумывать самостоятельно. В данном случае с самарским(Поволжье) и кемеровским(Сибирь) всё работает. Если происходят какие-то косяки, ставим log-level=0 и пересылаем им непонятки из bearerbox.log.
                    • 0
                      >> Это демон-надзиратель, который нужно дополнительно прописать в стартовые сценарии

                      Вот это место не особо понял :-S Парашют — это просто флажок -P в строке запуска.

                      А маршрутизировать по smsc, имхо, проще на уровне групп sendsms-user. В этом случае в строке запроса smsc фигурировать не будет, а всё будет рулиться автоматом smsbox'ом. По крайней мере мне так показалось настраивать удобнее.
                      • 0
                        --parachute
                        -P
                        Start watcher process. This process watch a child process and if child process crashed will restart them automatically.
                        • 0
                          Всё верно, и как это расходится с тем, что я сказал? :-)

                          Я просто уточнил, что ваше " демон-надзиратель, который нужно дополнительно прописать в стартовые сценарии", которое произносится с таинственным придыханием — это всего лишь маленький ключик в команде запуска :-))
                          • 0
                            Посмотрите официальные rc(init) сценарии. Там действительно отдельный демон — run_kannel_box.
                            /usr/local/sbin/run_kannel_box --pidfile /var/run/kannel/kannel_bearerbox.pid --min-delay 1 /usr/local/sbin/bearerbox /usr/local/etc/kannel.conf

                            А параметр --min-delay очень хорош при перезапуске, он заставляет запускаться значительно быстрее, в том числе при смерти дочернего процесса.
                            • 0
                              Я пользуюсь своими скриптами, в которых использую задокументированный параметр -P и в случае падения дочернего процесса (специально, через kill -9) я не успеваю выполнить ps ax до того, как парашют его поднимет заново.

                              Всё таки парашют — это -P. А отдельные скрипты — это отдельные скрипты.
                              • 0
                                Пожалуй вы правы, то что описано в статье — это не парашют, уберу сейчас.
                                Но это не отменяет того что в комплекте kannel идет отдельное приложение сделанное для того чтобы присматривать за падающими процессами.
                                • 0
                                  А вот этого, кстати, я не знал. Завтра как выйду на работу — нужно подробнее вопрос изучить.

                                  ps: а чем они принципиально лучше парашютов?

                                  pps: и вы кстати не обратили внимания на роутинг через логины. Параметр smsc в запросе — не айс ведь, согласитесь? :-)
                                  • 0
                                    Я не знаю чем они лучше/хуже, я использую стандартный сценарий rc и доверяю разработчикам в этом вопросе. Если вы говорите, что параметр -P запускает мгновенно, то, пожалуй, он лучше, т.к. в run_kannel_box просто каждые --min-delay секунд проверяется, запущен ли дочерний процесс и перезапускается, если не запущен. А по умолчанию это 10 секунд для каждого демона, что может потенциально привести к даунтайму до 20 секунд (запуск bearerbox + запуск smsbox). В моем случае с --min-delay 1 — даунтайм до 2 секунд. В принципе, тоже не успею проверить ps -A.
                        • 0
                          А на счет маршрутизации — можно вообще создать несколько smsboxов и прописывать роутинг, но это уже, пожалуй, более продвинутое использование. В принципе там можно делать весьма крутые штуки в зависимости от конктеста, почти так же как в asterisk для звонков.
                        • 0
                          можно менеджерский вопрос — имея этот гейтвей, компания все равно должна платить деньги операторам сотовой связи?

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