SMS and Email Responder: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary |
||
| (4 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 | ||
| Line 93: | Line 186: | ||
server.ehlo('x') | server.ehlo('x') | ||
server.login(######################,################) | server.login(######################,################) | ||
server.sendmail(' | server.sendmail('',toaddy,responce) | ||
def status(self,toaddy): | def status(self,toaddy): | ||
| Line 102: | Line 195: | ||
msg = MIMEText(stat+"\n\nTeach, Learn, Party") | msg = MIMEText(stat+"\n\nTeach, Learn, Party") | ||
msg['Subject'] = stat | msg['Subject'] = stat | ||
msg['From'] = " | msg['From'] = "" | ||
msg['To'] = toaddy | msg['To'] = toaddy | ||
return str(msg) | return str(msg) | ||
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()