SMS Server Tools 3

SMS шлюз на базе smstools

В свете введения изменений в работу сотовых операторов касающейся sms рассылок и значительного ужесточения требований к отправке сообщений с коротких номеров нет смысла платить деньги sms агрегаторам за возможность сделать рассылку по базе своих абонентов с использованием федерального номера. Конечно на сегодня есть масса аппаратных решений которые могут помочь в организации сервиса рассылки, но их цена пока очень высокая и нет гибкости в решении. Как всегда для реализации «домашнего» сервиса рассылки мы будем использовать CentOS, в качестве GSM модема можно использовать старый сотовый телефон, например Sony Ericsson j300 или не дорогой Cinterion MC35i Terminal (Siemens). Более подробный список совместимого оборудования можно уточнить на официальном сайте http://smstools3.kekekasvi.com

Установка

Предполагается что у вас уже установлен CentOS и вы подключили ваше устройство к серверу на com порт либо используете кабель COM to USB. В любом случае у вас в системе появилось ваше устройство. В моем случае я буду использовать /dev/ttyUSB0

Скачаем последнюю версию smstools3-3.1.15.tar.gz с официального сайта проекта и распакуем в директорию /root/smstools3. В распакованной папке smstools3 запустим install.sh

Конфигурационный файл smstools находится в папке /etc, его имя smsd.conf. Описание всех параметров можно найти на сайте разработчика, либо в директории /smstools3/examples. Мой конфигурационный файл выглядит следующим образом:

devices=GSM0
outgoing=/var/spool/sms/outgoing
checked=/var/spool/sms/checked
failed=/var/spool/sms/failed
incoming=/var/spool/sms/incoming
report=/var/spool/sms/report
sent=/var/spool/sms/sent
phonecalls=/var/spool/sms/phonecalls
logfile=/var/log/smsd.log
autosplit=3
loglevel=5
internal_combine=yes
incoming_utf8=yes
checkhandler=/usr/local/bin/ucsautoconvert
eventhandler=/usr/local/bin/eventhandler

[GSM0]
device=/dev/ttyUSB0
init=AT+CPMS=»ME»,»ME»,»ME»
report=yes
incoming=yes
send_delay=0
regular_run_cmd=AT+CUSD=1,»*105#»,15;
regular_run_interval=3600
regular_run_statfile=/var/log/sms_stat
sending_disabled=no
phonecalls=clip

Запустим smstools /etc/init.d/sms3 start. Если вы все правильно сделали в файле лога появится следующая запись:

2015-02-25 14:45:02,2, smsd: Smsd v3.1.14 started.
2015-02-25 14:45:02,2, smsd: Running as root:root.
2015-02-25 14:45:02,4, smsd: File mode creation mask: 022 (0644, rw-r—r—).
2015-02-25 14:45:02,5, GSM0: Modem handler 0 has started. PID: 2548.
2015-02-25 14:45:02,5, smsd: Outgoing file checker has started. PID: 2547.
2015-02-25 14:45:02,5, GSM0: Using check_memory_method 1: CPMS is used.
2015-02-25 14:45:07,5, GSM0: CGSN: 356194003354058
2015-02-25 14:45:07,5, GSM0: IMSI: 250203902029327

В директории /usr/local/bin вы можете найти исполняемые файлы smstools3, с помощью которых вы можете отправлять и обрабатывать входящие сообщения. Вы можете указать в конфигурационном файле каким скриптом обрабатывать входящие sms. За это отвечает параметр: eventhandler=/usr/local/bin/eventhandler

Я использую smstools3 для рассылки сообщений подписчикам между собой. Своего рода gsm пейджер. SMS шлюз получает сообщение, если в тексте сообщения стоит определенный цифровой префикс (префикс может быть любым) скрипт пробегает по базе префиксов и если находится нужный выполняет рассылку всем подписчикам или только группе подписчиков канала. Ниже приведу пример своего скрипта, на базе которого вы легко сможете сделать свой.

#!/bin/sh

# This is an example script that logs all events into an SQL database
# You need a MYSQL database as described in the documentation.
# Please read the documentation before using this script.

SQL_HOST=localhost
SQL_USER=smsd
SQL_PASSWORD=»Password»
SQL_DATABASE=smsd
SEND_TABLE=send
RECEIVED_TABLE=received

CAT=’/bin/$CAT’
ECHO=’/bin/echo’
FGREP=’/bin/fgrep’
AWK=’/bin/awk’
CUT=’/usr/bin/cut’
SED=’/bin/sed’
DATE=`date +»%y-%m-%d %H:%M:%S»`
#Extract data from the SMS file
FROM=`formail -zx From: < $2 | $SED ‘s/»//g’`
TO=`formail -zx To: < $2`
#Remove plus sign, spaces, minus and short number prefix
TO=`$ECHO «$TO» | $SED ‘s/ //g’ | $SED ‘s/+//g’ | $SED ‘s/s//g’ | $SED ‘s/-//g’`
SUBJECT=`formail -zx Subject: < $2`
SENT=`formail -zx Sent: < $2`
#Text is not u$SED but could be u$SED
ALPHABET=`grep -i Alphabet < $2`
if [ «$ALPHABET» = «Alphabet: ISO» ]; then
TEXT=`$SED -e ‘1,/^$/ d’ <$2 | iconv -f LATIN1 -t UTF8`
elif [ «$ALPHABET» = «Alphabet: UTF-8» ]; then
TEXT=`$SED -e ‘1,/^$/ d’ <$2`
else
TEXT=`$SED -e ‘1,/^$/ d’ <$2 | iconv -f UNICODEBIG -t UTF8`
fi

#Set some SQL parameters
if [ «$SQL_PASSWORD» != «» ]; then
SQL_ARGS=»-p$SQL_PASSWORD»;
else
SQL_ARGS=»»;
fi
SQL_ARGS=»-h $SQL_HOST -u $SQL_USER $SQL_ARGS -D $SQL_DATABASE -s -e»

#Insert a new entry into the SQL table

if [ «$1» = «FAILED» ] || [ «$1» = «SENT» ]; then
mysql $SQL_ARGS «insert into $SEND_TABLE (type,sent_time,sender,receiver,msgid,text) values (\»$1\»,\»$DATE\»,\»$FROM\»,\»$TO\»,\»$3\»,\»$TEXT\»);»;
elif [ «$1» = «RECEIVED» ]; then
mysql $SQL_ARGS «insert into $RECEIVED_TABLE (type,sent_time,received_time,sender,receiver,text) values (\»RECEIVED\»,\»$SENT\»,\»$DATE\»,\»$FROM\»,\»$SUBJECT\»,\»$TEXT\»»»);»;
elif [ «$1» = «REPORT» ]; then
#Extract more data from the status report file
DISCHARGE=`$SED -e 1,/SMS\ STATUS/d < $2 | formail -zx Discharge_timestamp:`
MSGID=`$SED -e 1,/SMS\ STATUS/d < $2 | formail -zx Message_id:`
STATUS=`$SED -e 1,/SMS\ STATUS/d < $2 | formail -zx Status: | $CUT -f1 -d,`

if [ «$MSGID» != «» ]; then
ID=`mysql $SQL_ARGS «select id from $SEND_TABLE where receiver=\»$FROM\» and type=\»SENT\» and msgid=\»$MSGID\» order by id desc limit 1;»`
mysql $SQL_ARGS «update $SEND_TABLE set received_time=\»$DISCHARGE\»,status=\»$STATUS\» where id=\»$ID\»;»
fi

fi

SQL_ARGS_RECEIVED=»-N —user=$SQL_USER —password=$SQL_PASSWORD $SQL_DATABASE -s»
if [ «$1» = «RECEIVED» ]; then
CODE=`$ECHO $TEXT | $AWK ‘{print $1}’ | tr «[:upper:]» «[:lower:]»`
if [ «$CODE» = «?» ]; then
FILE=`mktemp /var/spool/sms/outgoing/send_XXXXXX`
$ECHO «To:» $FROM > $FILE
$ECHO «Report: yes» >> $FILE
$ECHO «Flash: yes» >> $FILE
$ECHO «» >> $FILE
$ECHO «SELECT g_id, g_name FROM groups;» | mysql $SQL_ARGS_RECEIVED >> $FILE
elif [ «$CODE» = «911» ]; then
FILE1=`mktemp /var/spool/sms/outgoing/send1.XXXXXX`
$ECHO «To:» $FROM > $FILE1
$ECHO «Priority: High» >> $FILE1
$ECHO «Flash: yes» >> $FILE1
$ECHO «» >> $FILE1
$ECHO «Ваше сообщение принято к рассылке. Ожидайте помощи.» >> $FILE1
for user_sms in `$ECHO «SELECT s_phone FROM subscribers WHERE s_phone != »;» | mysql $SQL_ARGS_RECEIVED | $FGREP -v $FROM`
do
FILE2=`mktemp /var/spool/sms/outgoing/send2.XXXXXX`
$ECHO To: ${user_sms} > $FILE2
$ECHO «Report: yes» >> $FILE2
$ECHO «» >> $FILE2
$ECHO $TEXT «+»$FROM | $SED ‘/^’$CODE’ */!d; s///;q’ >> $FILE2
done
####send-email####################
for mailuser in `$ECHO «SELECT s_mail FROM subscribers WHERE s_mail != »;» | mysql $SQL_ARGS_RECEIVED | $FGREP -v $FROM`
do
$ECHO $TEXT «+»$FROM | $SED ‘/^’$CODE’ */!d; s///;q’ | mutt -s ‘An incoming sms channel 911’ ${mailuser}
done
########################
elif [ «$CODE» = «100» ]; then
FILE3=`mktemp /var/spool/sms/outgoing/send3.XXXXXX`
$ECHO «To:» $FROM > $FILE3
$ECHO «Priority: High» >> $FILE3
$ECHO «Flash: yes» >> $FILE3
$ECHO «» >> $FILE3
$ECHO «Ваше сообщение принято к рассылке.» >> $FILE3
for user in `$ECHO «SELECT s_phone FROM subscribers s LEFT JOIN sub_groups sg ON s.s_id=sg.sg_sid WHERE sg.sg_gid=$CODE AND s_phone != »;» | mysql $SQL_ARGS_RECEIVED | $FGREP -v $FROM`
do
FILE4=`mktemp /var/spool/sms/outgoing/send4.XXXXXX`
$ECHO To: ${user} > $FILE4
$ECHO «Report: yes» >> $FILE4
$ECHO «» >> $FILE4
$ECHO $TEXT «+»$FROM | $SED ‘/^’$CODE’ */!d; s///;q’ >> $FILE4
done
##send-email########################
for mailuser in `$ECHO «SELECT s_mail FROM subscribers s LEFT JOIN sub_groups sg ON s.s_id=sg.sg_sid WHERE sg.sg_gid=$CODE AND s_mail != »;» | mysql $SQL_ARGS_RECEIVED | $FGREP -v $FROM`
do
$ECHO $TEXT «+»$FROM | $SED ‘/^’$CODE’ */!d; s///;q’ | mutt -s ‘An incoming sms channel 100’ ${mailuser}
done
#################################
elif [ «$CODE» = «101» ]; then
FILE5=`mktemp /var/spool/sms/outgoing/send5.XXXXXX`
$ECHO «To:» $FROM > $FILE5
$ECHO «Priority: High» >> $FILE5
$ECHO «Flash: yes» >> $FILE5
$ECHO «» >> $FILE5
$ECHO «Ваше сообщение принято к рассылке.» >> $FILE5
for user in `$ECHO «SELECT s_phone FROM subscribers s LEFT JOIN sub_groups sg ON s.s_id=sg.sg_sid WHERE sg.sg_gid=$CODE;» | mysql $SQL_ARGS_RECEIVED | $FGREP -v $FROM`
do
FILE6=`mktemp /var/spool/sms/outgoing/send6.XXXXXX`
$ECHO To: ${user} > $FILE6
$ECHO «Report: yes» >> $FILE6
$ECHO «» >> $FILE6
$ECHO $TEXT «+»$FROM | $SED ‘/^’$CODE’ */!d; s///;q’ >> $FILE6
done
elif [ «$CODE» = «111» ]; then
FILE7=`mktemp /var/spool/sms/outgoing/send7.XXXXXX`
$ECHO «To:» $FROM > $FILE7
$ECHO «Report: yes» >> $FILE7
$ECHO «Flash: yes» >> $FILE7
$ECHO «» >> $FILE7
$CAT /etc/sms3/telephon >> $FILE7
elif [ «$CODE» = «888» ]; then
number=`$ECHO $TEXT | $SED ‘/^’$CODE’ */!d; s///;q’ | $CUT -d » » -f 1`
group_id=`$ECHO $TEXT | $SED ‘/^’$CODE’ */!d; s///;q’ | $SED ‘/^’$number’ */!d; s///;q’ | $CUT -d » » -f 1`
name=`$ECHO $TEXT | $SED ‘/^’$CODE’ */!d; s///;q’ | $SED ‘/^’$number’ */!d; s///;q’ | $SED ‘/^’$group_id’ */!d; s///;q’`
test_number=`$ECHO «SELECT s_phone FROM subscribers WHERE s_phone = $number» | mysql $SQL_ARGS_RECEIVED`
if [ «$number» = «$test_number» ];then
FILE8=`mktemp /var/spool/sms/outgoing/send8.XXXXXX`
$ECHO «To:» $FROM > $FILE8
$ECHO «Flash: yes» >> $FILE8
$ECHO «» >> $FILE8
$ECHO «Пользователь $name $number УЖЕ ЕСТЬ в системе.» >> $FILE8
else
$ECHO «insert into subscribers (s_id,s_phone,s_name) values (\»NULL\»,\»$number\»,\»$name\»)» | mysql $SQL_ARGS_RECEIVED
S_ID=`$ECHO «SELECT s_id FROM subscribers WHERE s_phone = $number» | mysql $SQL_ARGS_RECEIVED`
$ECHO «insert into sub_groups (sg_id,sg_sid,sg_gid) values (\»NULL\»,\»$S_ID\»,\»$group_id\»)» | mysql $SQL_ARGS_RECEIVED
testadd_number=`$ECHO «SELECT s_phone FROM subscribers s LEFT JOIN sub_groups sg ON s.s_id=sg.sg_sid WHERE sg.sg_gid= $group_id and s_phone = $number;»| mysql $SQL_ARGS_RECEIVED`
if [ «$number» = «$testadd_number» ];then
FILE9=`mktemp /var/spool/sms/outgoing/send9.XXXXXX`
$ECHO «To:» $FROM > $FILE9
$ECHO «Flash: yes» >> $FILE9
$ECHO «» >> $FILE9
$ECHO «Пользователь $name $number добавлен в систему.» >> $FILE9
FILE10=`mktemp /var/spool/sms/outgoing/send10.XXXXXX`
$ECHO «To:» $number > $FILE10
$ECHO «» >> $FILE10
$ECHO «Поздравляем $name с подключением к системе SMS оповещений МОТО канала $group_id.Занесите номер +78887776655 в Вашу записную книжку.Отправив знак ? на этот номер можно получить коды оповещений.С уважением,служба рассылки.» >> $FILE10
else
FILE11=`mktemp /var/spool/sms/outgoing/send11.XXXXXX`
$ECHO «To:» $FROM > $FILE11
$ECHO «Flash: yes» >> $FILE11
$ECHO «» >> $FILE11
$ECHO «Пользователь $name $number НЕ ДОБАВЛЕН в систему.» >> $FILE11
fi
fi
elif [ «$CODE» = «999» ]; then
number=`$ECHO $TEXT | $SED ‘/^’$CODE’ */!d; s///;q’ | $CUT -d » » -f 1`
test_number=`$ECHO «SELECT s_phone FROM subscribers WHERE s_phone = $number» | mysql $SQL_ARGS_RECEIVED`
if [ «$number» = «$test_number» ];then
S_ID=`$ECHO «SELECT s_id FROM subscribers WHERE s_phone = $number» | mysql $SQL_ARGS_RECEIVED`
$ECHO «DELETE FROM subscribers WHERE s_phone = $number ;» | mysql $SQL_ARGS_RECEIVED
$ECHO «DELETE FROM sub_groups WHERE sg_sid = $S_ID ;» | mysql $SQL_ARGS_RECEIVED
testdel_number=`$ECHO «SELECT s_phone FROM subscribers WHERE s_phone = $number» | mysql $SQL_ARGS_RECEIVED`
if [ «$number» = «$testdel_number» ];then
FILE12=`mktemp /var/spool/sms/outgoing/send12.XXXXXX`
$ECHO «To:» $FROM > $FILE12
$ECHO «Flash: yes» >> $FILE12
$ECHO «» >> $FILE12
$ECHO «Пользователь $name $number НЕ УДАЛЕН из системы.» >> $FILE12
else
FILE13=`mktemp /var/spool/sms/outgoing/send13.XXXXXX`
$ECHO «To:» $FROM > $FILE13
$ECHO «Flash: yes» >> $FILE13
$ECHO «» >> $FILE13
$ECHO «Пользователь $name $number УДАЛЕН из системы.» >> $FILE13
fi
else
FILE14=`mktemp /var/spool/sms/outgoing/send14.XXXXXX`
$ECHO «To:» $FROM > $FILE14
$ECHO «Flash: yes» >> $FILE14
$ECHO «» >> $FILE14
$ECHO «Пользователь $number ОТСУТСВУЕТ в системе.» >> $FILE14
fi
else
FILE15=`mktemp /var/spool/sms/outgoing/send15.XXXXXX`
$ECHO «To:» $FROM > $FILE15
$ECHO «Flash: yes» >> $FILE15
$ECHO «» >> $FILE15
$ECHO «Необходимо указать префикс.» >> $FILE15
fi

fi
if [ «$1» = «CALL» ]; then
TO=`formail -zx From: <$2`
FILE=`mktemp /tmp/send_XXXXXX`
echo «To: $TO» > $FILE
echo «» >> $FILE
echo «Этот номер только для SMS сообщений.» >> $FILE
FILE2=`mktemp /var/spool/sms/outgoing/send_XXXXXX`
mv $FILE $FILE2
fi

Создание базы smsd

Для работы рассылки как вы уже успели заметить необходима база данных. Я использую MySQL в которой вам необходимо создать базу с именем smsd и следующими таблицами:

  • groups
  • received
  • send
  • subscribers
  • sub_groups

Дамп базы smsd

— phpMyAdmin SQL Dump
— version 2.8.2.2
— http://www.phpmyadmin.net

— Хост: localhost
— Время создания: Фев 26 2015 г., 12:16
— Версия сервера: 5.0.26
— Версия PHP: 5.1.2

— БД: `smsd`

— ———————————————————


— Структура таблицы `groups`

CREATE TABLE `groups` (
`g_id` bigint(16) unsigned NOT NULL,
`g_name` varchar(255) character set utf8 collate utf8_unicode_ci NOT NULL,
`g_description` text character set utf8 collate utf8_unicode_ci NOT NULL,
PRIMARY KEY (`g_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

— ———————————————————


— Структура таблицы `received`

CREATE TABLE `received` (
`id` bigint(20) NOT NULL auto_increment,
`type` varchar(10) NOT NULL,
`sent_time` varchar(20) default NULL,
`received_time` varchar(20) default NULL,
`sender` varchar(30) default NULL,
`receiver` varchar(30) default NULL,
`text` varchar(255) character set utf8 collate utf8_unicode_ci default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=462 DEFAULT CHARSET=latin1 AUTO_INCREMENT=462 ;

— ———————————————————


— Структура таблицы `send`

CREATE TABLE `send` (
`id` bigint(20) NOT NULL auto_increment,
`type` varchar(10) NOT NULL,
`sent_time` varchar(20) default NULL,
`received_time` varchar(20) default NULL,
`sender` varchar(30) default NULL,
`receiver` varchar(30) default NULL,
`msgid` varchar(20) default NULL,
`text` longtext character set utf8 collate utf8_unicode_ci,
`status` varchar(20) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5042 DEFAULT CHARSET=latin1 AUTO_INCREMENT=5042 ;

— ———————————————————


— Структура таблицы `sub_groups`

CREATE TABLE `sub_groups` (
`sg_id` int(20) NOT NULL auto_increment,
`sg_sid` bigint(20) NOT NULL,
`sg_gid` bigint(20) NOT NULL,
PRIMARY KEY (`sg_id`)
) ENGINE=MyISAM AUTO_INCREMENT=67 DEFAULT CHARSET=latin1 AUTO_INCREMENT=67 ;

— ———————————————————


— Структура таблицы `subscribers`

CREATE TABLE `subscribers` (
`s_id` bigint(20) NOT NULL auto_increment,
`s_phone` char(11) character set utf8 collate utf8_unicode_ci NOT NULL,
`s_name` varchar(255) character set utf8 collate utf8_unicode_ci NOT NULL,
`s_mail` varchar(100) character set utf8 collate utf8_unicode_ci NOT NULL,
PRIMARY KEY (`s_id`)
) ENGINE=MyISAM AUTO_INCREMENT=96 DEFAULT CHARSET=latin1 AUTO_INCREMENT=96 ;

SMS шлюз на базе smstools: 4 комментария

  1. Виктор Петрович

    Да, хороший проект был. Жалко что закончилось его развитие. Да и телефонов с поддержкой com порта сейчас днем с огнем не сыскать. Одни смарфоны.

    1. Алексей Орлов Автор записи

      Добрый день, Виктор Петрович. То что сейчас тяжело найти поддерживаемые телефоны это точно. И то что рынок запалили смартфоны полностью с Вами согласен. Технологии не стоят на месте, но никто не запрещает использовать gsm роутеры. Например тот что описан в статье.

  2. St.Nikolov

    Скрипт является непригодным для использования из-за символов «» «»
    Было бы лучше, если есть ссылку на скачивание , жаль

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *