SMS and Email Responder

From Unallocated Space
Revision as of 14:05, 6 September 2011 by C-P (talk | contribs)
Jump to navigation Jump to search

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('uasstatus@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'] = "uasstatus@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):
            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()