Pull to refresh

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

Lumber room
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, там помогут.
Tags: мегафонопсосыkannelsms-гейтsmssmppsms-сервис
Hubs: Lumber room
Total votes 26: ↑22 and ↓4 +18
Comments 26
Comments Comments 26

Popular right now