SMS-чат на коленках

image

Понадобился нам как-то смс-чат для небольшой группы пользователей. Основными требованиями были надежность и простота реализации. В наличии был средненький офисный компьютер с Windows ХР на борту, USB-модем Huawei E1550, сим-карта с положительным балансом и среднестатистический эникейщик.

Хотелось нам следующего: инженеры из числа оперативного персонала, заступая на дежурство, подключаются к группе чата и могут обмениваться между собой короткими текстовыми сообщениями. Это полезно при решении проблем, касающихся нескольких отделов (релейщиков и энергетиков, например). Когда присутствие в группе не требуется – можно выйти и сообщения не получать.

Теоретически все было просто. Берем GSM-модем, пишем программу, которая проверяет на нем входящие сообщения, выдергивает из них нужную информацию, производит обработку и передает по списку подключенных абонентов.

На практике все оказалось иначе. Активное гугление привело нас на несколько проектов, в том числе и на Хабр. Но все оказались довольно сложными. Ибо Delphi из нас никто особо не понимает, а проекты для Линукса мы не рассматривали в принципе – у нас все машины виндовые.

Последней находкой стала программа от питерской компании Headwind Solutions. Называется она «Персональный СМС Сервер». Программа платная, но есть 30 дней демо-режима. Мы начали ковырять ее.

Программа оказалась очень удобной и надежной. Основная фишка ее в том, что она избавляет от необходимости работать с модемом напрямую. Она сама работает с GSM-модемом, проверяет входящие сообщения и отправляет исходящие. Если поступает новое вызывает скрипт и передает ему два параметра: номер отправителя и текст сообщения. Все остальное решается скриптом. Уже из скрипта можно вызывать процедуру отправки сообщения в программу. Сообщений может быть много, программа сама поставит их в очередь на отправку и грамотно передаст. Скрипт написан на VBS.

Программа, кстати, может работать как служба Windows. Мы сначала проигнорировали эту возможность и совершенно напрасно служба работает стабильнее.

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

Подробнее остановимся на скрипте чата. Помимо самого скрипта, в том же каталоге понадобится создать три файла: hlr.txt, vlr.txt и vlr_back.txt.
Первый файл заполняем номерами абонентов, имеющих доступ к чату. Формат такой: мобильный номер без плюса <пробел> идентификатор абонента.

79111234567 Иванов (энергетик)
79111234568 Петров (WDM)
79111234569 Сидоров (RRL)

Второй и третий файлы оставляем пустыми. Во втором хранятся записи о вошедших в группу абонентах, а третий файл используется скриптом для добавления/удаления абонента из группы.

Скрипт поддерживает три команды. Начинаются они со знака # (решетка). Чтобы войти в группу чата нужно отправить смс на номер сим-карты модема с текстом #1, чтобы выйти #0. Для запроса текущего списка пользователей нужно отправить #?
Запросы от абонентов, не вошедших в группу, игнорируются.

Входящие сообщения обрабатываются следующим образом. В начало исходного сообщения ставится идентификатор абонента (у нас это фамилия сотрудника и его отдел), а затем это сообщение передается всем абонентам из файла vlr.txt. Отправитель получает квитанцию об отправке сообщения. В ней дублируется его сообщение и количество абонентов, которому оно отправлено. Передача квитанции была добавлена в качестве контрольной меры. Если квитанция получена, значит, чат исправен, деньги на сим-карте есть и всем участникам чата сообщение улетело.

Привожу наши настройки программы. Параметры подбирались несколько лет методом проб и ошибок:

image

И собственно скрипт:

Код чата на VBS

' Получаем значения переменных, которые передаются скрипту при его вызове Number = WScript.Arguments(0) Message = WScript.Arguments(1) Message = Trim(Message)   ' Обнуляем флаги, устанавливаем значение переменных FlagVlr = 0 FlagHlr = 0 FlagRX = 0 FlagSymbol=0 Users = "" Count = 0   ' Устанавливаем соответствие между переменными и именами файлов vlr = "vlr.txt" hlr = "hlr.txt" vlr_back = "vlr_back.txt"   ' Ищем номер абонента в списке HLR Set objFSO = CreateObject("Scripting.FileSystemObject") Set filehlr = objFSO.OpenTextFile(hlr, 1)  Do Until filehlr.AtEndOfStream     sLine = filehlr.ReadLine()     nSpace = InStr(sLine, " ")          If nSpace > 0 Then     Number_hlr = Left(sLine, nSpace - 1)     Name_hlr = Trim(Right(sLine, Len(sLine) - nSpace))     End If        If (Number_hlr = Number) Then     FlagHlr = 1     Name = Name_hlr     End If          If (Len(Users) = 2) Then     Users = ""     End If Loop filehlr.Close   ' Ищем номер абонента в списке VLR Set objFSO = CreateObject("Scripting.FileSystemObject") Set filevlr = objFSO.OpenTextFile(vlr, 1)  Do Until filevlr.AtEndOfStream     sLine = filevlr.ReadLine()     nSpace = InStr(sLine, " ")          If nSpace > 0 Then     Users = Users & ", "     Number_vlr = Left(sLine, nSpace - 1)     Name_vlr = Trim(Right(sLine, Len(sLine) - nSpace))     End If        Count = Count + 1      If (Number_vlr = Number) Then     FlagVlr = 1     Name = Name_vlr     End If           If (Len(Users) = 2) Then     Users = ""     End If      Users = Users & Name_vlr Loop filevlr.Close   ' Устанавливаем флаги в зависимости от наличия записи номера в файлах HLR и VLR  If (FlagHlr = 0) Then Flaguser = 0 End If   If (FlagHlr = 1) And (FlagVlr = 0) Then Flaguser = 1 End If   If (FlagHlr = 1) And (FlagVlr = 1) Then Flaguser = 2 End If   ' Устанавливаем значение текстовых сообщений  MessageAlreadyEnter = "Вы уже вошли в чат. Сейчас в группе: " & Users & "." MessageNowInGroup = "Сейчас в группе: " & Users & "." MessageEmpty = "Вы отправили пустое сообщение."   ' Устанавливаем значение текстовых сообщений при пустой группе  If (Count = 0) Then MessageNowInGroup = "В группе нет собеседников." End If  If (Count = 1) Then MessageAlreadyEnter = "Вы уже вошли в чат. В группе нет собеседников." End If   ' Обработка специальных сообщений  dlina = Len(Message) symbol = Trim(Message) symbol = Left(symbol, 1) If (symbol = "#") Then FlagSymbol = 1 End If   ' Обработка запроса на вход в группу  If (Message = "#1") And (Flaguser = 1) Then FlagVlr = 0 FlagSymbol = 0  Set filevlr = objFSO.OpenTextFile(vlr, 1) Set filevlrback = objFSO.OpenTextFile(vlr_back, 2) rec = Number + " " + Name filevlrback.WriteLine(rec)  Do Until filevlr.AtEndOfStream 	sw = filevlr.ReadLine() 	filevlrback.WriteLine(sw) 	Loop  filevlr.Close filevlrback.Close  Set filevlr = objFSO.OpenTextFile(vlr, 2) Set filevlrback = objFSO.OpenTextFile(vlr_back, 1) Do Until filevlrback.AtEndOfStream 	sw = filevlrback.ReadLine() 	filevlr.WriteLine(sw) 	Loop  filevlr.Close filevlrback.Close   ' ======= Отправляем сообщение об успешном входе в группу =======  Set objSMSDriver = CreateObject("HeadwindGSM.SMSDriver") objSMSDriver.Connect() Set objMsg = CreateObject("HeadwindGSM.SMSMessage") objMsg.To = Number objMsg.Body = "Вы успешно подключились к разговору. " + MessageNowInGroup objMsg.Send() End If   ' Обработка запроса на вход в группу, если абонент уже находится в ней  If (Message = "#1") And (Flaguser = 2) Then FlagVlr = 0 FlagSymbol = 0  Set objSMSDriver = CreateObject("HeadwindGSM.SMSDriver") objSMSDriver.Connect() Set objMsg = CreateObject("HeadwindGSM.SMSMessage") objMsg.To = Number objMsg.Body = "Вы уже подключены к разговору. " + MessageNowInGroup objMsg.Send() End If   ' Обработка повторного запроса на выход из группы  If (Message = "#0") And (Flaguser = 1) Then FlagSymbol = 0 End If   ' Обработка запроса на выход из группы  If (Message = "#0") And (FlagVlr = 1) Then FlagVlr = 0 FlagSymbol = 0   Set filevlr = objFSO.OpenTextFile(vlr, 1) Set filevlrback = objFSO.OpenTextFile(vlr_back, 2)  Do Until filevlr.AtEndOfStream 	sLine = filevlr.ReadLine() 	nSpace = InStr(sLine, " ")      	If nSpace > 0 Then 	Number_vlr = Left(sLine, nSpace - 1) 	Name_vlr = Trim(Right(sLine, Len(sLine) - nSpace)) 	rec = Number_vlr + " " + Name_vlr 	End If    	If (Number_vlr <> Number) Then 	filevlrback.WriteLine(rec) 	End If        Loop  filevlr.Close filevlrback.Close  Set filevlr = objFSO.OpenTextFile(vlr, 2) Set filevlrback = objFSO.OpenTextFile(vlr_back, 1) Do Until filevlrback.AtEndOfStream rec = filevlrback.ReadLine() filevlr.WriteLine(rec) Loop filevlr.Close filevlrback.Close   ' ======= Отправляем сообщение об успешном выходе из группы =======  Set objSMSDriver = CreateObject("HeadwindGSM.SMSDriver") objSMSDriver.Connect() Set objMsg = CreateObject("HeadwindGSM.SMSMessage") objMsg.To = Number objMsg.Body = "Вы успешно покинули группу." objMsg.Send()  End If   ' Обработка запроса на получение списка собеседников  If (Message = "#?") And (FlagVlr = 1) Then FlagVlr = 0 FlagSymbol = 0  Set objSMSDriver = CreateObject("HeadwindGSM.SMSDriver") objSMSDriver.Connect() Set objMsg = CreateObject("HeadwindGSM.SMSMessage") objMsg.To = Number objMsg.Body = MessageNowInGroup objMsg.Send() End If   ' Обработка неверной или несуществующей команды  If (FlagSymbol = 1) And (FlagHlr = 1) Then FlagVlr = 0 FlagSymbol = 0  Set objSMSDriver = CreateObject("HeadwindGSM.SMSDriver") objSMSDriver.Connect() Set objMsg = CreateObject("HeadwindGSM.SMSMessage") objMsg.To = Number objMsg.Body = "Команда не распознана. Команды: #1 - вход, #0 - выход, #? - список собеседников." objMsg.Send()  End If   ' Обработка пустого сообщения  If (Message = "") And (FlagVlr = 1) Then FlagVlr = 0  Set objSMSDriver = CreateObject("HeadwindGSM.SMSDriver") objSMSDriver.Connect() Set objMsg = CreateObject("HeadwindGSM.SMSMessage") objMsg.To = Number objMsg.Body = MessageEmpty objMsg.Send() End If   ' Обработка непустого сообщения  If (FlagVlr = 1) Then 		Message = Trim(Message) 		Set objFSO = CreateObject("Scripting.FileSystemObject") 		Set filevlr = objFSO.OpenTextFile(vlr, 1) 		Set objSMSDriver = CreateObject("HeadwindGSM.SMSDriver") 		objSMSDriver.Connect() 		Do Until filevlr.AtEndOfStream 		sLine = filevlr.ReadLine 		nSpace = InStr(sLine, " ") 			If nSpace > 0 Then 			Number_buffer = Left(sLine, nSpace - 1) 			Name_buffer = Trim(Right(sLine, Len(sLine) - nSpace)) 				If (Number_buffer <> Number) Then 				Set objMsg = CreateObject("HeadwindGSM.SMSMessage") 				objMsg.To = Number_buffer 				objMsg.Body = Name & ": " & Message 				objMsg.Send() 				End If 			End If Loop filevlr.Close  Count_receipt = Count - 1  ' ======= Отправляем квитанцию =======  Set objMsg = CreateObject("HeadwindGSM.SMSMessage") objMsg.To = Number objMsg.Body = "Message send to " & Count_receipt & " users. Text: '" & Message & "'" objMsg.Send()  ' ======= /Отправляем квитанцию =======   End If   ' ======= Конец скрипта =======  WScript.Quit 

Таким макаром мы получили простенький СМС-чат, который сейчас трудится на благо отечественных инженеров. Надеемся, что пригодится и вам.

ссылка на оригинал статьи http://habrahabr.ru/post/259057/

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

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