# -*- coding: utf-8 -*- import re import urllib from hashlib import md5 from ssl import _create_unverified_context from django.conf import settings from django.utils.translation import ugettext as _ from servo.models.common import Configuration class BaseSMSProvider: def __init__(self, recipient, note, msg): self.conf = Configuration.conf() if not self.conf.get('sms_http_sender'): raise ValueError(_("SMS sender not configured")) if len(recipient) < 8: recipient = '372' + recipient recipient = re.sub(r'[\+\s\-]', '', recipient) self.recipient = recipient.lstrip('+') self.note = note self.msg = msg self.sender = self.conf['sms_http_sender'] self.body = self.note.body.encode('utf-8') class SMSJazzProvider: """ SMS Jazz gateway provider Used mainly by Estonian AASPs, hence default prefix of 372 """ URL = 'https://www.smsjazz.net/SMSjazzAPI/sendsms.php' STATUSES = { '1' : ('DELIVERED', 'SMS message is delivered to mobile phone'), '2' : ('FAILED', 'SMS message has failed and is not delivered to mobile phone'), '4' : ('SENT', 'SMS message is buffered and is waiting to be delivered to mobile phone'), '8' : ('SENT', 'SMS message is buffered and is waiting to be delivered to mobile phone'), '16': ('FAILED', 'Error in sender/receiver/message parameters'), '32': ('SENT', ''), } def __init__(self, recipient, note, msg): if len(recipient) < 8: recipient = '372' + recipient recipient = re.sub(r'[\+\s\-]', '', recipient) self.recipient = recipient.lstrip('+') self.note = note self.msg = msg def send(self): """ Sends SMS through SMS Jazz Gateway """ conf = Configuration.conf() if not conf.get('sms_http_sender'): raise ValueError(_("SMS sender name not configured")) body = self.note.body.encode('utf-8') sender = conf.get('sms_http_sender') pwhash = md5(conf['sms_http_password']).hexdigest() checksum = md5(body + self.recipient.encode('ascii') + pwhash).hexdigest() params = { 'username' : conf['sms_http_user'], 'password' : pwhash, 'message' : body, 'sender' : sender.encode('ascii', 'replace'), 'receiver' : self.recipient, 'charset' : 'UTF8', 'checksum' : checksum, } if self.msg: dlruri = '/api/messages/?id={0}&status=%status%'.format(self.msg.code) dlruri = settings.SERVO_URL + dlruri params['dlruri'] = dlruri params = urllib.urlencode(params) r = urllib.urlopen(self.URL, params, context=_create_unverified_context()).read() if not '1:OK' in r: raise ValueError(_('Failed to send message to %s') % self.recipient) class HQSMSProvider(BaseSMSProvider): """ HQSMS Gateway Provider. API docs: http://www.hqsms.com/media/page/docs/HQSMS_https.pdf """ URL = "https://api.smsapi.com/sms.do" BACKUP_URL = "https://api2.smsapi.com/sms.do" ERRORS = { "ERROR:13" : _("Lack of valid phone numbers (invalid or blacklisted numbers)"), "ERROR:14" : _("Wrong sender name"), "ERROR:19" : _("Too many messages in one request"), "ERROR:52" : _("Too many attempts of sending messages to one number (maximum 10 attempts whin 60s)"), "ERROR:102" : _("Invalid username or password"), "ERROR:103" : _("Insufficient credits on your account"), "ERROR:200" : _("Unsuccessful message submission"), "ERROR:201" : _("Internal system error"), "ERROR:999" : _("Internal system error"), } STATUSES = { '401' : ('NOT_FOUND', 'Wrong ID or report has expired'), '402' : ('EXPIRED', 'Messages expired'), '403' : ('SENT', 'Message is sent'), '404' : ('DELIVERED', 'Message is delivered to recipient'), '405' : ('UNDELIVERED', 'Message is undelivered (invalid number, roaming error etc)'), '406' : ('FAILED', 'Sending message failed – please report it to us'), '407' : ('REJECTED', 'Message is undelivered (invalid number, roaming error etc)'), '408' : ('UNKNOWN', 'No report (message may be either delivered or not)'), '409' : ('QUEUED', 'Message is waiting to be sent'), '410' : ('ACCEPTED', 'Message is delivered to operator'), } def send(self): pwhash = md5(self.conf['sms_http_password']).hexdigest() params = { 'username' : self.conf['sms_http_user'], 'password' : pwhash, 'message' : self.body, 'from' : self.sender, 'to' : self.recipient, } if self.msg: dlruri = settings.SERVO_URL + '/api/messages/?id={0}'.format(self.msg.code) params['notify_url'] = dlruri params = urllib.urlencode(params) r = urllib.urlopen(self.URL, params, context=_create_unverified_context()).read() if 'ERROR:' in r: raise ValueError(self.ERRORS.get(r, _('Unknown error (%s)') % r)) def set_status(self, msg): pass class HttpProvider: """ Sends SMS through a HTTP gateway (ie Kannel) """ def send(self, note, number): conf = Configuration.conf() if not conf.get('sms_http_url'): raise ValueError(_("No SMS HTTP gateway defined")) params = urllib.urlencode({ 'username' : conf['sms_http_user'], 'password' : conf['sms_http_password'], 'text' : note.body.encode('utf8'), 'to' : number }) f = urllib.urlopen("%s?%s" % (conf['sms_http_url'], params), context=_create_unverified_context()) return f.read()