SMS and Email Responder

From Unallocated Space
Revision as of 06:49, 10 October 2011 by C-P (talk | contribs) (moved Occupancy Sensor email and text message responder to SMS and Email Responder: New functions dictate a change in naming.)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Responder V2.0

Version 2.0 actually uses botfunc (respfunc is a symlink to botfunc) of the IRC_BOT for its commands code, and an upgraded polling and response setup using IMAP and SMTP.


#!/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,msg])
	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")
	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()