SMS and Email Responder
Here is the code for the sensor responder using gmail and google voice -Textile
#!/usr/bin/python2.6
import imaplib,smtplib,re,urllib,urllib2,time
from email.mime.text import MIMEText
import pdb
class emailResponder:
def __init__(self):
#list of trigger words
self.trigger = ['status','address']
def parse(self):
fromaddy = None
subject = None
self.body.reverse()
for field in self.body:
if field[:5] == 'From:':
fromaddy = field.split('<')[-1][:-1]
elif field[:8] == 'Subject:':
subject = field.split(' ')[1].strip().lower()
if subject not in self.trigger:
subject = None
if fromaddy and subject != None:
return (fromaddy,subject)
else: return False
def getMessage(self,msg):
if msg == 'status':
f = open('/tmp/status','r')
stat = f.read()
f.close()
return stat
elif msg == 'address':
return "512 Shaw Court suite 105\nSevern, MD 21122"
def getUnread(self):
"""
get unread messages and return subject and from address
"""
self.messages = {}
mbox = imaplib.IMAP4_SSL('imap.gmail.com', 993)
mbox.login(*****,*****)
status, count = mbox.select('EmailResponder')
#print count #number of total messages
typ, data = mbox.search(None, 'UNSEEN')
for num in data[0].split():
typ, data = mbox.fetch(num, '(RFC822)')
self.body = data[0][1].split('\r\n')
data = self.parse()
if data is not False:
self.messages[data[0]] = {"subject":data[1],"from":data[0]}
mbox.close()
mbox.logout()
def sendRespond(self,responce,toaddy):
server = smtplib.SMTP("smtp.gmail.com",587)
server.ehlo('x')
server.starttls()
server.ehlo('x')
server.login(*****,*****)
server.sendmail('*****@gmail.com',toaddy,responce)
def status(self,toaddy):
"""
format the responce from the sensor into an email message and return it
"""
stat = self.getMessage(self.messages[toaddy]['subject'])
msg = MIMEText(stat+"\n\nTeach, Learn, Party")
msg['Subject'] = stat
msg['From'] = "*****@gmail.com"
msg['To'] = toaddy
return str(msg)
def respond(self):
self.getUnread()
if len(self.messages) == 0:
return
else:
for key in self.messages.keys():
toaddy = self.messages[key]['from']
self.sendRespond(
self.status(toaddy),toaddy)
class textResponder:
def __init__(self):
#list of trigger words
self.trigger = ['status','address']
def getUnread(self):
"""
get unread messages and return subject and from address
"""
self.messages = {}
mbox = imaplib.IMAP4_SSL('imap.gmail.com', 993)
mbox.login(*****,*****)
status, count = mbox.select('TXTMESSAGE')
#print count #number of total messages
typ, data = mbox.search(None, 'UNSEEN')
for num in data[0].split():
typ, data = mbox.fetch(num, '(RFC822)')
self.body = data[0][1].split('\r\n')
data = self.parse()
if data is not False:
#we do this so multiple text messages are not sent to the same user
#its a hack but it works
self.messages[data[0]] = {"from":data[0],"msg":data[1]}
mbox.close()
mbox.logout()
def parse(self):
fromaddy = None
msg = None
self.body.reverse()
for field in self.body:
if field[:5] == 'From:':
fromaddy = field.split('<')[-1][:-1].split('.')[1]
elif field.lower() in self.trigger:
msg = field.lower()
if fromaddy and msg != None:
return (fromaddy,msg)
else: return False
def getMessage(self,msg):
if msg == 'status':
f = open('/tmp/status','r')
stat = f.read()
f.close()
return stat
elif msg == 'address':
return "512 Shaw Court suite 105\nSevern, MD 21122"
def respond(self):
self.getUnread()
#check to see if there are any messages to be sent and return
if len(self.messages) == 0:
return
gv = GoogleVoiceLogin(*****,*****)
if not gv.logged_in:
print "voice login failed"
return
for number in self.messages.keys():
text_sender = TextSend(gv.opener, gv.key)
text_sender.text = self.getMessage(self.messages[number]['msg'])
text_sender.send_text(number)
#following 5 lines are used for debug
#if text_sender.responce:
# print text_sender.responce
# print "success"
#else:
# print "failed"
#sleep so as not to have google think we are trying to txt message spam
time.sleep(3)
class TextSend():
"""
text send coded taken from here
http://everydayscripting.blogspot.com/2009/08/python-google-voice-mass-sms-and-mass.html
"""
def __init__(self, opener, key):
self.opener = opener
self.key = key
self.sms_url = "https://www.google.com/voice/sms/send/"
self.text = ''
def send_text(self, phone_number):
sms_params = urllib.urlencode({
'_rnr_se': self.key,
'phoneNumber': phone_number,
'text': self.text
})
#send the text
self.responce = self.opener.open(self.sms_url, sms_params).read()
class GoogleVoiceLogin:
"""
gvoice code from here
http://everydayscripting.blogspot.com/2009/08/python-google-voice-mass-sms-and-mass.html
"""
def __init__(self, email, password):
# Set up our opener
self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
urllib2.install_opener(self.opener)
# Define URLs
self.loing_page_url = 'https://www.google.com/accounts/ServiceLogin'
self.authenticate_url = 'https://www.google.com/accounts/ServiceLoginAuth'
self.gv_home_page_url = 'https://www.google.com/voice/#inbox'
# Load sign in page
login_page_contents = self.opener.open(self.loing_page_url).read()
# Find GALX value
galx_match_obj = re.search(r'name="GALX"\s*value="([^"]+)"', login_page_contents, re.IGNORECASE)
galx_value = galx_match_obj.group(1) if galx_match_obj.group(1) is not None else ''
# Set up login credentials
login_params = urllib.urlencode( {
'Email' : email,
'Passwd' : password,
'continue' : 'https://www.google.com/voice/account/signin',
'GALX': galx_value
})
# Login
self.opener.open(self.authenticate_url, login_params)
# Open GV home page
gv_home_page_contents = self.opener.open(self.gv_home_page_url).read()
# Fine _rnr_se value
key = re.search('name="_rnr_se".*?value="(.*?)"', gv_home_page_contents)
if not key:
self.logged_in = False
else:
self.logged_in = True
self.key = key.group(1)
if __name__ == "__main__":
emailResponder().respond()
textResponder().respond()