Как автоматизировать отправку SMS с webcalldirect

Добавлю к заголовку "… с помощью языка Python".
Не так давно обнаружилась необходимость в получении мною сообщений о событиях на удаленной от меня точке, на каковой точке впрочем присутствовал компьютер с убунтой и интернетом. Простейший вывод был — ну конечно! Вот пусть компьютер и отправляет мне SMS с обзором последних событий!
После некоторых раздумий и изучения материалов уже решенных проблем я получил следующие выводы:

1. Отправка SMS по email2sms на мой киевстаровский номер… вобщем работает, но иногда с задержкой до суток, при том что более-менее гарантировано всего 90% доставки. А с нового 2011 года у них появился лимит на 150 сообщений, что было хоть и не решающей, но последней каплей против.

2. Отправка SMS через календарь google, что также легко пишется на Python и удивительно надёжно работает. Но очень маленькая ёмкость одного сообщения, избыточная информация в начале сообщения не дали мне в полной мере насладиться этим сервисом. И кроме того, неизвестно сколько времени ещё продлится эта замечательная шара у google…

3. Обратив внимание на платные сервисы отправки SMS и персмотрев кучу предложений я остановился на этом. Такой себе VOIP сервис, webcalldirect, когда-то давно я перешел на него со Скайпа (только для платных звонков) после прочтения какой-то статьи на Хабре.

Несмотря на то что раз в пару месяцев цена на звонки и SMS у них подрастает, стоимость одной SMS в 0,038 евроцента для меня кажется очень приемлемой до сих пор. И нет необходимости покупть SMS (тысячи их) а промышленных масштабах и быть для этого только юрлицом.
Однако, нужно иметь аккаунт webcalldirect, и на нем немножко денег.

И поскольку я с недавнего времени фанат языка прогаммирования Python, то заодно и посмотрим как можно быстро и со вкусом решать с его помощью различные проблемы… (о которых мы бы и не знали если бы компьютеров не существовало)

Просмотрев мануалы, я увидел что если отправить на сайт webcalldirect запрос типа:

"https://www.webcalldirect.com/myaccount/sendsms.php?username=%s?&password=%s&from=%s&to=%s&text=%s"
 

при этом подставив в %s соответствущие параметры, то сообщение успешно приходит и, конечно, со счёта снимается сумма примерно в полтора рубля.
Что же, тогда пишем простейшую обертку для этой универсальной строки:
1. Создаём класс

class webcalldirect_sms():
 

и в нем пока 2 функции — создать sms и отправить sms

def set_msg_body(self, _msg = 'none'):
 if len(_msg) > self._webcall_char_limit:
 print "Message has", len(_msg), "characters. This is longer than", self._webcall_char_limit, "and SMS will be cut!"
 self._body = _msg[:self._webcall_char_limit]
 else:
 print "Message has", len(_msg), "characters. Accepted."
 self._body = _msg
 #end if-else
 
 self.replace_chars() 
 # url for an actual SMS sending:
 self._url_result = self._url_begin+self._username+'&password='+self._password+'&to='+self._to_phone+'&text='+self._body 
 
 def send_sms(self, _msg='none'):
 self.set_msg_body(_msg)
 try:
 f = urllib2.urlopen(self._url_result)
 msg = f.read()
 return self.status_from_xml(msg)
 except:
 print "ERROR in sending sms!"
 print traceback.print_exc() 
 return "ERROR!" 
 

Cообщения будут урезаны до максимально приемлемой длины в 160 символов.
Все пробелы в url нжно заменить на '%20'(и не спрашивайте меня почему):

def replace_chars(self):
 # Follow replacement you MUST HAVE for use webcalldirect SMS:
 self._body = self._body.replace(' ', '%20') # no whitespaces allowed in url, use %20 instead.
 

Проверим статус нашего сообщения. Логика тут двоичная — либо сообщение отправилось, либо нет:

def status_from_xml(self, _txt_to_parce):
 i = _txt_to_parce.find("")+14
 j = _txt_to_parce.find("")
 _status = "\nSMS status: " + _txt_to_parce[i:j]
 if _status != 'success':
 i = _txt_to_parce.find("")+13
 j = _txt_to_parce.find("")
 _error = _txt_to_parce[i:j]
 _status = _status + ". " + _error
 #end if
 return _status 
 

Как водится, разбираться в xml парсерах ради двух строчек resultstring мне было лень…

Нам нужен ещё конструктор класса, в котором будем задавать параметры идентификации пользователя, и телефонный номер абонента:

def __init__(self, w_user, w_recepient):
 self._url = "https://www.webcalldirect.com/myaccount/sendsms.php?username=%s?&password=%s&from=%s&to=%s&text=%s"
 self._url_begin = 'https://www.webcalldirect.com/myaccount/sendsms.php?username='
 self._webcall_char_limit = 160 
 self._username = w_user._username
 self._password = w_user._password
 self._from_addr = w_user._from_addr
 self._to_phone = w_recepient._to_phone

print "SMS to phone:", self._to_phone
 

Конструктор принимает 2 параметра — объект класса, содержащий информацию об аккаунте и объект класса, содержащий телефонный номер абонента. Быстренько набросаем оба эти класса:

class webcall_recepient():
 def __init__(self, _number = 0):
 if _number:
 self._to_phone = _number
 else:
 # Here put a deafult phone number:
 self._to_phone = '+XXXXXXXXXXX'
 #end webcall_recepient

class webcall_user():
 def __init__(self):
 self._username = 'XXXXXXXXXXX'
 self._password = 'XXXXXXXXXXX'
 self._from_addr = 'N' # this field is not in use, but present in speqs.
 #end webcall_user
 

Понятное дело, все прописные иксы в этих двух классах нужно заменить на параметры Вашего аккаунта в webclldirect'e и на номер куда собственно будет отправляться sms. Ещё желательно вынести оба класса в отдельные файлы и спрятать от любопытных глаз в бинарный формат. Но это уже дело вкуса и личной паранойи.

Как будем использовать наши классы и объекты? Cледующим простейшим образом:

# main entrance point:
 if __name__ == "__main__": 
 _account = webcall_user()
 _to = webcall_recepient('+XXXXXXXXXXX')
 sender = webbcalldirect_sms(_account, _to)
 
 _user_input = raw_input('\nPlease enter your SMS message:\n > ')
 # _user_input = 'Hello. This is a text message from webCallDirect! -Name- npuBeT. Ckywaj-ka ew4e eTux Mqrkux FpaHzy3ckux 6yLok ga BbInej-ka 4aI0. -Name-'
 print sender.send_sms(_user_input) 
 print "END."
 

Значение параметра _user_input можно задавать непосредственно в коде, с клавиатуры в консоли, читать из файла, и всё тому подобное.

В планах — вынести отправку sms и проверку статуса отправки в отдельный поток, чтобы не тормозить основной цикл и не замораживать «gui», если пользователь захочет отправить десяток-другой гневных (или наоборот) sms-ок своему абоненту из консоли. И добавить команду ":q" для выхода из программы.

Вот и всё.


0 комментариев

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