Прием смс
Рассылать смс сегодня нетрудно — регистрируемся в одном из многочисленных сервисах рассылок, вносим сумму и вперед. А как принимать смс от граждан в автоматическом режиме?
Короткие номера не подходит, ибо они навек закрепили за собой репутацию лохотрона. К тому же нужно вводить префикс, а минимальная стоимость 4 рубля. Принимать только на короткие номера — верх свинства по отношению к абонентам.
А ведь все можно сделать своими руками! Берем простой 3Г-модем, втыкаем в него местную симку (я взял Мегафон), подключаем к компьютеру, ставим драйвера. Проверяем, появился ли в системе модем.
Качаем замечательную утилиту Гамму, а конкретно — виндовые бинарники (не Minimal, а обычные). Распаковываем.
Утилита gammu может рулить модемом программно, например, читать и
отправлять смс, совершать звонки, делать бекапы содержимого телефона и
массу других полезных штук. В комплекте идет gammu-smsd
— демон для
чтения смс в фоновом режиме. Он постоянно проверяет наличие смс,
складывает их в базу данных и вызывает заданную команду в момент
прихода новой смски.
Теперь о том, как все настроить. В папке bin создаем файл smsdrc
следующего содержания:
[gammu]
device = COM6:
connection = at
[smsd]
Service = sql
Driver = native_mysql
User = user
Password = password
PC = xxx.xxx.xxx.xxx
Database = smsd
PIN = 8730
LogFile = smsd.log
RunOnReceive = smsd_callback.bat
Стартуем демона:
gammu-smsd --config smsdrc
Секция [gammu]
в конфигурации отвечает за параметры соединения с
устройством. device — номер КОМ-порта, узнать его можно в свойствах
модема, connection — тип соединения, для 3Г-модема обычно at.
Раздел [smsd]
содержит параметры демона. Как видно, в качестве базы
я использую Мускуль. Опция PIN задает пин-код симки (если защита ПИН
не отключена). LogFile — текстовый файл логов.
Самое интересное — RunOnReceive
, это имя команды, скрипта или
батника, который будет вызываться при получении смс. Параметры
сообщения передаются в переменных окружения SMS_1_NUMBER
,
SMS_1_TEXT
и др.
В батнике у меня прописан вызов питоньего скрипта:
start pythonw path\to\smsd_callback.py
Почему бы сразу не вызвать скрипт? Потому, что вызов осуществляется в том же потоке, что и чтение смс, поэтому пока не завершится процесс команды, чтение будет приостановлено. А в данном случае батник вызывает скрипт и сразу закрывается.
Фрагмент кода на питоне:
number = os.environ["SMS_1_NUMBER"]
message = os.environ["SMS_1_TEXT"]
msg_pattern = r"\d+"
account, value = re.findall(msg_pattern, message)[:2]
statement = Statement(account=account, value=value)
statement.save()
answer = u"Принято. Абонент %s, показание %s" % (account, value)
send_sms(answer, number)
Получаем номер и сообщение, находим в нем пару чисел — лицевой счет и показание прибора. Сохраняем в базу и отвечаем абоненту, что все в порядке.
Комментарии из старого блога
11/04/13 Сергей: Статья интерсная, много нового узнал, пытаясь запустить. Но нет ничего про структуру базы. Мануалов гаммы на русском нет. Вот и как бы статья по прямому предназначению “Прием смс” (профи и без статьи организует) пока не очень полезна.
11/05/13 Иван Гришаев: Структуру базы можно посмотреть в .sql-файле, который лежит где-то в папке с программой.
11/07/13 Сергей: Спасибо. Теперь вот такая картина в логфайле (тут я баран)) поможете??? подключаю 3g модем - железка от алкател.
Thu 2013/11/07 15:09:29 gammu-smsd[2452]: Connected to Database: smsd on localhost
Thu 2013/11/07 15:09:29 gammu-smsd[2452]: Connected to Database native_mysql: smsd on localhost
Thu 2013/11/07 15:09:29 gammu-smsd[2452]: Created Windows RW shared memory at 003A0000
Thu 2013/11/07 15:09:29 gammu-smsd[2452]: Starting phone communication...
Thu 2013/11/07 15:09:40 gammu-smsd[2452]: Error at init connection: No response in specified timeout. Probably phone not connected. (TIMEOUT[14])
Thu 2013/11/07 15:09:40 gammu-smsd[2452]: Already hit 250 errors
Thu 2013/11/07 15:09:40 gammu-smsd[2452]: Terminating communication: No response in specified timeout. Probably phone not connected. (TIMEOUT[14])
Thu 2013/11/07 15:09:40 gammu-smsd[2452]: Starting phone communication...
Thu 2013/11/07 15:09:50 gammu-smsd[2452]: Error at init connection: No response in specified timeout. Probably phone not connected. (TIMEOUT[14])
Thu 2013/11/07 15:09:50 gammu-smsd[2452]: Already hit 250 errors
Thu 2013/11/07 15:09:50 gammu-smsd[2452]: Terminating communication: No response in specified timeout. Probably phone not connected. (TIMEOUT[14])
Thu 2013/11/07 15:09:50 gammu-smsd[2452]: Starting phone communication...
11/07/13 Иван Гришаев: Пишет, что нет соединения с телефоном.
Сначала нужно указать проге, какой порт слушать. Создайте файл
Gammu\bin\gammurc
(без расширения), в нем пишете:
[gammu]
device = COM6:
connection = at
только вместо COM6 - ваш порт. Двоеточие на конце нужно.
11/07/13 Сергей: Я так и делал, модем откликается (в терминале) на сом3,4,5 в диспетчере оборудования модем=сом5.
[gammu]
device = COM
пробовал все результат почти один, 3 и 5 сукунд через 10 закрывается гамми, ком4 каждые 10-20 сек перепроверяет соединение с телефоном, пока сам не закрою.
11/07/13 Иван Гришаев: Вспомнил - для смс-демона нужен отдельный
конфиг! Gammu\bin\smsdrc
У меня он такой:
[gammu]
device = COM5:
connection = at
[smsd]
Service = sql
Driver = native_mysql
User = username
Password = passowrd
PC = 172.27.86.8
Database = smsd
LogFile = smsd.log
RunOnReceive = some_bat_file.bat
CheckSecurity = 0
CheckBattery = 0
11/07/13 Сергей: Не помогло добавление Check ов. Нарыл гдето другой терминал, вот он АТ командами смски вытягивает. А можно както на питоне опросить АТ командами com порт? Думаю так проще будет.
11/07/13 Иван Гришаев: Конечно можно, есть либа для ком-порта: http://pyserial.sourceforge.net/
Кстати, вы пробовали http://www.simplesms.ru/ ? Прога очень хорошая, разработчик - русский, есть документация и форум.
11/07/13 Сергей: Хороший вы (я не против и на ты) человек. С библиотекой буду разбираться (инглиша не знаю), а платные вещи отпадают я имено хочу разобраться и сделать - типа хобби). Можно вообще не париться - 800р/мес и прикрутить их API к своему сервису, я так и делал, но как то не уютно))).
11/07/13 Сергей: надо же скрипт php заработал, раньше порты были 14,15,16 и не работало. Попробую на php получалку сделать!
$telnumb='904*****37';
$sms_text='poluchilos';
$format = "AT+CMGF=1\r\n";
$tel = "at+cmgs=\"+7".$telnumb."\"\r\n ";
$text = $sms_text.chr(26)."\r\n ";
$fp = fopen ("COM3:", "w");
flock($fp,LOCK_EX);
if(!$fp){
echo "COM-Port not opened";
}
else{
fwrite($fp, $format);
sleep(1);
fwrite($fp, $tel);
sleep(1);
fwrite($fp, $text);
sleep(1);
flock($fp,LOCK_UN);
echo $format.$tel.$text;
}
$fp = fclose ($fp);
11/07/13 Иван Гришаев: Сообщения с кириллицей нормально приходят? А сообщения из нескольких частей?
11/07/13 Сергей: Нет под w1251 все усложняется, там меняется алгоритм сборки, но это решаемо. Мне прием нужен, его и ковыряю. На php отправить оказывается просто, а вот принять “одна темнота” пока, т.что гамми, питон не закрываю.
11/07/13 Сергей: Так то все дожно быть просто. Всего то нужно в
порт заслать "AT+CMGL=4\r\n"
и получить все что он отдаст. А потом
раскодить, распарсить. Ну нннникак.
11/08/13 Иван Гришаев: Да, кириллица хранится в последовательностях UFT-16, кажется. Придется декодировать.
11/07/13 Сергей: Еще об отправке, там без подтверждения получения смс абонентом и по той же причине - читать порт не получается.
11/07/13 Сергей: simplesms пробовал скачать - антивирус заблокировал(((
11/08/13 Иван Гришаев: А вы разблокируйте.
Нашли ошибку? Выделите мышкой и нажмите Ctrl/⌘+Enter