SMS and Email Responder: Difference between revisions
Jump to navigation
Jump to search
(Created page with "Here is the code for the sensor responder using gmail and google voice -Textile <pre> #!/usr/bin/python2.6 import imaplib,smtplib,re,urllib,urllib2,time from email.mime.text imp...") |
No edit summary |
||
(5 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
The Unallocated Space SMS and Email Responder is a way for people to interact with the space and access certain functions and information over SMS or Email. | |||
Commands are currently as follows: | |||
*'''status''' returns the current open/closed status of the space. | |||
*'''rollcall''' returns a list of people who have checked into the space using the beta member check-in system. | |||
*'''tweet''' returns the contents of the latest @Unallocated twitter post. | |||
*'''site''' returns the latest blog post from the space website. | |||
*'''sign''' returns the current contents of the prolite [[LED_Sign]], and updates the content if used with any further text. (sign this is the new sign text. | |||
*'''weather''' returns the current weather conditions in Severn MD. | |||
*'''address''' returns the address of the space. | |||
The number to SMS is +1 (512) 943-2827, this number can also be called to check the open/closed status of the space as well as speak to someone in the space. Those functions and more are detailed here: [[Asterisk]] | |||
*Version 1.0 was written by Textile, and is no longer in use. | |||
*Version 2.0 was written by C-P and actually uses botfunc (respfunc is a symlink to botfunc) of the [[IRC_Bot]] for its commands code, and has an upgraded polling and response setup using IMAP and SMTP. | |||
---- | |||
== Version 2.0 == | |||
<pre> | |||
#!/usr/bin/env python | |||
import email,imaplib,smtplib,os,respfunc | |||
def send_response(toaddrs,msg): | |||
print "Sending response to "+toaddrs | |||
print msg | |||
server=smtplib.SMTP('smtp.gmail.com:587') | |||
server.starttls() | |||
server.login('','') | |||
server.sendmail('',toaddrs,"\r\n"+msg+"\r\n") | |||
server.quit() | |||
def get_emails(email_ids): | |||
data=[] | |||
for e_id in email_ids: | |||
_,response=imap_server.fetch(e_id,'(RFC822)') | |||
mail=email.message_from_string(response[0][1]) | |||
msg='' | |||
for part in mail.walk(): | |||
if str(part.get_content_type())=='text/plain': | |||
msg=msg+str(part.get_payload()) | |||
msg=msg.split('--')[0].strip() | |||
sender=email.utils.parseaddr(mail['from'])[1] | |||
data.append([sender.replace("'",''),msg.replace("'",'')]) | |||
return data | |||
imap_server=imaplib.IMAP4_SSL("imap.gmail.com",993) | |||
imap_server.login('','') | |||
imap_server.select('INBOX') | |||
email_ids=str(imap_server.search(None,'(UNSEEN)')[1])[2:-2].split() | |||
for em in get_emails(email_ids): | |||
if "postmaster.twitter.com" in em[0]: #Twitter mention | |||
print "unused" | |||
#em[1]=em[1].replace("=\r\n",'') | |||
#em[1]=em[1].replace("'",'') | |||
#em[1]=em[1].replace('"','') | |||
#em[1]=em[1].split(" you:\r\n\r\n")[1].split("\r\n\r\n\r\nReply")[0].split("\r\n\r\nIn reply to")[0].strip() | |||
#print em[1] | |||
#os.system("echo 'New Twitter Mention: "+em[1]+"' > /uas/irc/irc") | |||
elif "unallocated@unallocatedspace.org" == em[0]: #wiki alert | |||
data=em[1].split('<{0}>')[1].split() | |||
os.system("echo 'Wiki Update: Page %s by %s: %s' > /uas/irc/irc" % (data[0], data[1], data[2])) | |||
else: | |||
print "From: "+em[0] | |||
print "Message: "+em[1] | |||
print | |||
em[1]=em[1].partition(" ") | |||
command=em[1][0].replace('!','') | |||
command=command.lower() | |||
if command in respfunc.responder_commands: | |||
send_response(em[0],respfunc.responder_commands[command](em[1][2])) | |||
imap_server.close() | |||
imap_server.logout() | |||
</pre> | |||
---- | |||
== Version 1 is depreciated == | |||
Here is the code for the sensor responder using gmail and google voice | Here is the code for the sensor responder using gmail and google voice | ||
-Textile | -Textile | ||
<pre> | <pre>#!/usr/bin/python2.6 | ||
#!/usr/bin/python2.6 | import imaplib,smtplib,re,urllib,urllib2,time,socket | ||
import imaplib,smtplib,re,urllib,urllib2,time | |||
from email.mime.text import MIMEText | from email.mime.text import MIMEText | ||
import pdb | import pdb,os | ||
class actions: | |||
def __init__(self): | |||
pass | |||
def status(self,X=None): | |||
f = open('/tmp/status','r') | |||
stat = f.read() | |||
f.close() | |||
return stat | |||
def address(self,X=None): | |||
return "512 Shaw Court suite 105\nSevern, MD 21122" | |||
def sign(self,data): | |||
data=data.replace('"','') | |||
data=data.replace("'",'') | |||
try: | |||
if data=="": | |||
message='The last sign update read as: '+open('/tmp/sign','r').read() | |||
else: | |||
if '<FO>' in data: | |||
message="<FO> is not allowed" | |||
else: | |||
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) | |||
s.connect(('127.0.0.1',9001)) | |||
s.sendall(data) | |||
message=s.recv(1024) | |||
s.close() | |||
if "Updating sign to " in message: | |||
os.system("echo 'Mobile update to sign: "+data+"' > /uas/irc/irc") | |||
except socket.error: | |||
message="Failed to update sign" | |||
return message | |||
class emailResponder: | class emailResponder: | ||
def __init__(self): | |||
cmd = actions() | |||
self.trigger = {'status':cmd.status,'address':cmd.address,'sign':cmd.sign} | |||
self.msg = None | |||
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() | |||
self.msg = ' '.join(field.split(' ')[1:]) | |||
if subject not in self.trigger.keys(): | |||
subject = None | |||
if fromaddy and subject != None: | |||
return (fromaddy,subject) | |||
else: return False | |||
def getMessage(self,msg): | |||
if msg in self.trigger.keys(): | |||
return self.trigger[msg](self.msg) #call function | |||
else: | |||
return "Invalid Command" | |||
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('',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'] = "" | |||
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: | class textResponder: | ||
def __init__(self): | |||
cmd = actions() | |||
self.trigger = {'status':cmd.status,'address':cmd.address,'sign':cmd.sign} | |||
self.msg = None | |||
self.fromaddy = None | |||
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 based on email history | |||
#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] | |||
self.fromaddy = fromaddy | |||
elif field.lower().split(' ')[0] in self.trigger.keys(): | |||
msg = field.lower().split(' ')[0] | |||
self.msg = ' '.join(field.lower().split(' ')[1:]) | |||
if fromaddy and msg != None: | |||
return (fromaddy,msg) | |||
else: return False | |||
def getMessage(self,msg): | |||
if msg in self.trigger.keys(): | |||
return self.trigger[msg](self.msg) #call function | |||
else: | |||
return "Invalid Command" | |||
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(): | 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: | 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__": | if __name__ == "__main__": | ||
emailResponder().respond() | |||
textResponder().respond() | |||
</pre> | </pre> |
Latest revision as of 13:25, 25 October 2011
The Unallocated Space SMS and Email Responder is a way for people to interact with the space and access certain functions and information over SMS or Email. Commands are currently as follows:
- status returns the current open/closed status of the space.
- rollcall returns a list of people who have checked into the space using the beta member check-in system.
- tweet returns the contents of the latest @Unallocated twitter post.
- site returns the latest blog post from the space website.
- sign returns the current contents of the prolite LED_Sign, and updates the content if used with any further text. (sign this is the new sign text.
- weather returns the current weather conditions in Severn MD.
- address returns the address of the space.
The number to SMS is +1 (512) 943-2827, this number can also be called to check the open/closed status of the space as well as speak to someone in the space. Those functions and more are detailed here: Asterisk
- Version 1.0 was written by Textile, and is no longer in use.
- Version 2.0 was written by C-P and actually uses botfunc (respfunc is a symlink to botfunc) of the IRC_Bot for its commands code, and has an upgraded polling and response setup using IMAP and SMTP.
Version 2.0
#!/usr/bin/env python import email,imaplib,smtplib,os,respfunc def send_response(toaddrs,msg): print "Sending response to "+toaddrs print msg server=smtplib.SMTP('smtp.gmail.com:587') server.starttls() server.login('','') server.sendmail('',toaddrs,"\r\n"+msg+"\r\n") server.quit() def get_emails(email_ids): data=[] for e_id in email_ids: _,response=imap_server.fetch(e_id,'(RFC822)') mail=email.message_from_string(response[0][1]) msg='' for part in mail.walk(): if str(part.get_content_type())=='text/plain': msg=msg+str(part.get_payload()) msg=msg.split('--')[0].strip() sender=email.utils.parseaddr(mail['from'])[1] data.append([sender.replace("'",''),msg.replace("'",'')]) return data imap_server=imaplib.IMAP4_SSL("imap.gmail.com",993) imap_server.login('','') imap_server.select('INBOX') email_ids=str(imap_server.search(None,'(UNSEEN)')[1])[2:-2].split() for em in get_emails(email_ids): if "postmaster.twitter.com" in em[0]: #Twitter mention print "unused" #em[1]=em[1].replace("=\r\n",'') #em[1]=em[1].replace("'",'') #em[1]=em[1].replace('"','') #em[1]=em[1].split(" you:\r\n\r\n")[1].split("\r\n\r\n\r\nReply")[0].split("\r\n\r\nIn reply to")[0].strip() #print em[1] #os.system("echo 'New Twitter Mention: "+em[1]+"' > /uas/irc/irc") elif "unallocated@unallocatedspace.org" == em[0]: #wiki alert data=em[1].split('<{0}>')[1].split() os.system("echo 'Wiki Update: Page %s by %s: %s' > /uas/irc/irc" % (data[0], data[1], data[2])) else: print "From: "+em[0] print "Message: "+em[1] print em[1]=em[1].partition(" ") command=em[1][0].replace('!','') command=command.lower() if command in respfunc.responder_commands: send_response(em[0],respfunc.responder_commands[command](em[1][2])) imap_server.close() imap_server.logout()
Version 1 is depreciated
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,socket from email.mime.text import MIMEText import pdb,os class actions: def __init__(self): pass def status(self,X=None): f = open('/tmp/status','r') stat = f.read() f.close() return stat def address(self,X=None): return "512 Shaw Court suite 105\nSevern, MD 21122" def sign(self,data): data=data.replace('"','') data=data.replace("'",'') try: if data=="": message='The last sign update read as: '+open('/tmp/sign','r').read() else: if '<FO>' in data: message="<FO> is not allowed" else: s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(('127.0.0.1',9001)) s.sendall(data) message=s.recv(1024) s.close() if "Updating sign to " in message: os.system("echo 'Mobile update to sign: "+data+"' > /uas/irc/irc") except socket.error: message="Failed to update sign" return message class emailResponder: def __init__(self): cmd = actions() self.trigger = {'status':cmd.status,'address':cmd.address,'sign':cmd.sign} self.msg = None 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() self.msg = ' '.join(field.split(' ')[1:]) if subject not in self.trigger.keys(): subject = None if fromaddy and subject != None: return (fromaddy,subject) else: return False def getMessage(self,msg): if msg in self.trigger.keys(): return self.trigger[msg](self.msg) #call function else: return "Invalid Command" 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('',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'] = "" 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): cmd = actions() self.trigger = {'status':cmd.status,'address':cmd.address,'sign':cmd.sign} self.msg = None self.fromaddy = None 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 based on email history #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] self.fromaddy = fromaddy elif field.lower().split(' ')[0] in self.trigger.keys(): msg = field.lower().split(' ')[0] self.msg = ' '.join(field.lower().split(' ')[1:]) if fromaddy and msg != None: return (fromaddy,msg) else: return False def getMessage(self,msg): if msg in self.trigger.keys(): return self.trigger[msg](self.msg) #call function else: return "Invalid Command" 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()