def TogglePhones(log_file, actions): voice = Voice() voice.login() exceptions = [] for phone in voice.phones: if phone.phoneNumber in REVERSE_NUMBERS: phone_name = REVERSE_NUMBERS[phone.phoneNumber] if phone_name in actions: action = actions[phone_name] try: if action.state == phones_pb2.Action.ENABLED: prefix = 'Enabling' phone.enable() else: prefix = 'Disabling' phone.disable() print '%s %s: %s for change at %s' % ( prefix, phone_name, phone.phoneNumber, util.FormatTime(action.time_ms)) except Exception as e: print e exceptions.append(e) voice.logout() if exceptions: raise Exception(exceptions)
def run(self): i = 0 # Create new Google Voice instance and login voice = Voice() voice.login(self.username, self.password) while True: i += 1 voice.sms() for msg in self.extractsms(voice.sms.html): if msg: if self.debug: print(msg) # Write user number and message to data file for webserver caller = msg["from"].replace("+", "").replace(":", "") print(msg["time"] + '\t' + caller + '\t' + msg["text"], file=open("data.tsv", "a")) # Parse and format message using Language class replyRaw = self.language.reply(msg["text"]) replyFormatted = self.language.format(replyRaw) print(type(replyFormatted)) print(msg["time"] + '\t' + "17408720211" + '\t' + replyFormatted, file=open("data.tsv", "a")) replyFormatted = replyFormatted.replace("\t", "\n") # Send reply message with patient information back to user voice.send_sms(caller, str(replyFormatted)) # Delete previously read messages from Google Voice for message in voice.sms().messages: if message.isRead: message.delete() if self.debug: print('Idle Counter: ' + str(i)) time.sleep(self.timer) voice.logout()
class Connection(SuperConn): """Manages connection with Google Voice""" def get_messages(self): """Retrieve messages from GV connection and return MessageSet instance""" return gv_convos_to_messages(self) def send(self,msg): """Send a message using this GV connection.""" #Should we check if it's sending a message to itself? self.check_num_format(msg.to_num) #raises exception if not right format self.voice.send_sms(msg.to_num,msg.text) def __init__(self,cid,**creds): """Connection to Google Voice. optional keyword args: GV_USER=<str>, GV_PASSWORD=<str> (if none provided will prompt)""" self.voice = Voice() print "logging in to GV account %s" % creds['GV_USER'] self.voice.login(email=creds['GV_USER'],passwd=creds['GV_PASSWORD']) self.id = cid self.num = self.voice.settings['primaryDid'] self.backend = 'pygooglevoice' def __delete__(self): self.voice.logout()
def send_error(server_info, phone_number): voice = Voice() voice.login() text = server_info + ' NEEDS HELP. :(' voice.send_sms(phone_number, text) voice.logout()
def send_sms(PHONE, MESSAGE): voice = Voice() voice.login() voice.send_sms(PHONE, MESSAGE) voice.logout() return 1
def convoid(self, send="", pas="", id=""): # take url args send, pas, and id html = [] voice = Voice() voice.login(send, pas) voice.inbox() # load google voice inbox messages = [] for msg in extractConvo(voice.inbox.html, id): msgs = u"%s" % msg["text"] # encode text as Unicode msgs = msgs.replace("\n", " ") # replace new lines with spaces fr = str(msg["from"]) # get the sender's name total = "" total = fr + " " + msgs + "\n" # create the total string messages.append(total) voice.logout() json.dumps(None) return json.dumps(messages) # return info as JSON
def generate(self, num="0000000000", msg="", send="", pas=""): # Take URL args num, msg, send, and pas number = "" number = num voice = Voice() msg = msg.replace("%20", " ") voice.login(send, pas) voice.send_sms(number, msg) voice.logout() return ( """ <h1>To: """ + number + " Message:" + msg + """ </h1> """ ) # Return the HTML
def getmsgs(self, send="", pas=""): # take args send and pas html = [] voice = Voice() voice.login(send, pas) voice.inbox() # load google voice inbox messages = [] ids = [] last = "" inbox = settings.FEEDS[0] for message in getattr(voice, inbox)().messages: ids.append(message.items()[7][1]) for id in ids: all = extractConvo(voice.inbox.html, id) lengthAll = len(all) for group in all[0 : lengthAll - 1]: messages.append([group[u"text"], group[u"from"]]) messages.append(ids) voice.logout() json.dumps(None) return json.dumps(messages) # return this info as JSON
class HsaTextNotifier: def __init__(self, email, password): self.voice = Voice() self.email = email self.password = password self.numbers = [] self.interests = [] self.profile = config.Standby self.status = HsaStatusType.STANDBY def StatusListener(self, status): for index in range(len(self.numbers)): if self.status != status \ and status in self.interests[index]: self.SendMsg(self.numbers[index], \ "Status changed to "+status+" in profile "+self.profile.profileName) self.status = status def ProfileListener(self, profile): for index in range(len(self.numbers)): if self.profile != profile \ and profile.profileName in self.interests[index]: self.SendMsg(self.numbers[index], "Profile changed to "+profile.profileName) self.profile = profile def AddPhoneDest(self, number, changeOfInterest): self.numbers.append(number) self.interests.append(changeOfInterest) def SendMsg(self, number, msg): try: self.voice.login(self.email,self.password) self.voice.send_sms(number, msg) self.voice.logout() except: print "Error with text notification"
class sms: def __init__( self, logger, db ): self.voice, self.user, self.passwd = Voice(), 'USERNAME_GOES_HERE', 'PASSWORD_GOES_HERE' self.log, self.db = logger.write, db self.voice.login( self.user, self.passwd ) def pullTexts( self, purge=False ): messages = self.voice.sms().messages if not messages: self.log( 'MOD_SMS', 'No New Messages Were Received' ) return self.log( 'MOD_SMS', 'New Messages Received, Now Parsing' ) for msg in messages: if not msg.isRead: user, cmd = msg[ 'phoneNumber' ], msg[ 'messageText' ].lower() if '!remove' in cmd: self.db.remove( user ) else: self.db.insert( user ) if purge: msg.delete() self.voice.logout() def spam( self, message ): for user in self.db.dump(): self.log( 'MOD_SMS', 'Currently Spamming {}'.format( user ) ) self.voice.send_sms( user, message ) self.voice.logout() def spamNew( self, message ): for user in self.db.dump_new(): self.log( 'MOD_SMS', 'Currently Spamming {} With Last Update'.format( user ) ) self.voice.send_sms( user, message ) self.voice.logout()
class GVChat(Chat): """ Implements a google voice chat client. """ def __init__(self, user, password): self.gv = Voice() self.gv.login(user, password) self.to_phone = None self.to_name = None self.polltime = 30 self.step = 0 # fire immediately so that we have data to display Chat.__init__(self) self.register_event(1, self._update_poll_time) def status(self): """ Draw a fancy status bar displaying the person's name and phone number. """ if self.to_phone: phone = '(%s) %s - %s' % (self.to_phone[:3], self.to_phone[3:6], self.to_phone[6:]) else: phone = '' name = self.to_name if self.to_name else '' return ' poll in %ds | %s | %s ' % (self.step, name, phone) def _update_poll_time(self): if self.step == 0: self.getsms() self.step = self.polltime else: self.step -= 1 return True # always keep polling def getsms(self): """ Update the GVChat object with the first SMS thread in your SMS box. """ # We could call voice.sms() directly, but I found this does a rather # inefficient parse of things which pegs a CPU core and takes ~50 CPU # seconds, while this takes no time at all. data = self.gv.sms.datafunc() data = re.search(r'<html><\!\[CDATA\[([^\]]*)', data, re.DOTALL).groups()[0] divs = SoupStrainer('div') tree = BeautifulSoup(data, parseOnlyThese=divs) # We need to know who to send texts to, as that information is # not included with each message. msgtype = str(tree.find("span", attrs={"class": "gc-message-type"})) m = re.search('\((\d{3})\) (\d{3})-(\d{4})', msgtype) self.to_phone = ''.join(m.groups()) smses = [] # we only want the first conversation conversation = tree.find("div", attrs={"id": True}, recursive=False) msgs = conversation.findAll(attrs={"class": "gc-message-sms-row"}) for row in msgs: msgitem = {"id": conversation["id"]} spans = row.findAll("span", attrs={"class": True}, recursive=False) for span in spans: cl = span["class"].replace('gc-message-sms-', '') msgitem[cl] = (" ".join(span.findAll(text=True))).strip() if msgitem["text"]: msgitem["text"] = BeautifulStoneSoup( msgitem["text"], convertEntities=BeautifulStoneSoup.HTML_ENTITIES ).contents[0] smses.append(msgitem) # Now that we have the SMSes, we can add their text and render them. self.curses_lock.acquire() # If smses is shorter than history, we started a new thread, so clear the # history. if len(smses) < len(self.history): self.history = [] self.chatscreen.clear() def sublist_index(haystack, needle): """ Find the starting index of a sublist in a list. Premature optimization is the root of all evil. The empty list is a sublist of every point in a list. """ try: for i in xrange(len(haystack)): if haystack[i:i + len(needle)] == needle: return i except IndexError: pass raise ValueError # only print new messages try: msgs = map(lambda m: m['from'] + ' ' + m['text'], smses) idx = sublist_index(msgs, self.history) smses = smses[idx + len(self.history):] except ValueError: # if we didn't find anything, then print everything pass for sms in smses: name = sms["from"][:-1] if name != 'Me': self.to_name = name # if we're adding a message that's not from me, beep curses.beep() self.message(name, sms["text"]) self.curses_lock.release() def __exit__(self, type, value, traceback): self.gv.logout() Chat.__exit__(self, type, value, traceback) def send(self, msg): if not self.to_phone: raise ValueError("No phone number :-(") # BeautifulSoup chokes on some characters, and they will cause GVChat to # break until a new SMS thread is started. Typically, these characters # aren't in text messages, but they are easily accidentally pressed on the # keyboard. We remove them here and warn the user. for c in ']': if c in msg: msg = string.replace(msg, c, '') self.gv.send_sms(self.to_phone, msg) # We could use self.message() or wait until the next poll to alert the user # that we sent the message, but we might as well check for new messages # while we're sending. self.getsms()
class GoogleVoiceBackend(BackendBase): _title = "googlevoice" #or pyGoogleVoice? # number of seconds to wait between # polling the modem for incoming SMS POLL_INTERVAL = 10 # time to wait for the start method to # complete before assuming that it failed MAX_CONNECT_TIME = 10 def configure(self, **kwargs): #if Voice is None: # raise ImportError( # "The lumin.backends.googlevoice engine is not available, " + # "because 'pygooglevoice' is not installed or not on the current path." # ) self.config = ConfigParser.ConfigParser() import lumin self.config.read(os.path.join(os.path.dirname(lumin.__file__), '.gvoice'))#TODO make sure that this is reading from the project root directory, not the same directory as where this file is placed #make sure we have at least the required parameters if self.config == [] or (not self.config.has_option('login', 'email') or not self.config.has_option('login', 'password')): raise ImportError( #TODO is importerror really what we want to use? "The lumin.backends.googlevoice engine is not available, " + "because a .gvoice configuration file in the root of the project " + "with login and password attributes does not exist." ) def __str__(self): return self._title def send(self, message): try: #TODO this is based on the assumption that the googlevoice method will throw exceptions (it returns None) self.voice.send_sms( str(message.connection.identity), message.text ) except: self.info(sys.exc_info()) #log the exception self.failed_messages += 1 return False self.sent_messages += 1 return True def status(self): vars = { "_title": self.title, "Messages Sent": self.sent_messages, "Messages Received": self.received_messages } #TODO see if we can pull data from googlevoice object return vars def run(self): while self.running: self.info("Polling google voice for messages") messages = self.voice.inbox().messages #poll it, this will return conversations, not individual messages #google voice works like gmail: #it automatically groups individual texts into conversations by #phone number and similar timestamps (texts relatively close #in time will be grouped together) status = json.loads(self.voice.inbox.json) html = self.voice.inbox.html if status['unreadCounts']['sms'] >= 1 : #check for new conversations for key in status['messages'].keys() : phone_number = status['messages'][key]['phoneNumber'] #TODO figure out this datetime stuff #datetime = datetime.fromtimestamp(int(status['messages'][key]['startTime'])/1000) #google gives three decimal places of precision, take it off #date = #this date time will have some problems, #the json gives us a unix time stamp but that's updated every time we add something to the conversation; #the parsed datetime from the html can be shorthand/etc. #TODO (critical) another problem here is that everytime we get a reply, the entire conversation is returned #so we replay the entire conversation everytime we get a text to add onto it, we either need to retrieve # individual messages from google voice, or somehow separate these conversations up into atomic blocks texts = re.findall( re.escape(phone_number) + r'\:\s*\<\/span\>\s*\<span\s+class="gc\-message\-sms\-text"\>(.*?)\<\/span\>', html, re.S ) for text in texts : identity = ''.join(re.findall(r'[0-9]+', phone_number)) message = self.message(identity, text) #, datetime) self.router.incoming_message(message) for message in messages : #message.mark() message.delete()# TODO so this is to try to break conversations into atomic messages #todo may be easier way to do this? just search for received messages that have not been read? flags for that? #in:unread to:me # wait for POLL_INTERVAL seconds before continuing # (in a slightly bizarre way, to ensure that we abort # as soon as possible when the backend is asked to stop) for n in range(0, self.POLL_INTERVAL*10): if not self.running: return None #means we skip the self.info below...break out of the top loop? time.sleep(0.1) self.info("Run loop terminated.") def start(self): try: self.sent_messages = 0 self.failed_messages = 0 self.received_messages = 0 self.info("Connecting via googlevoice...") self.voice = Voice() result = self.voice.login(email=self.config.get('login','email'), passwd=self.config.get('login','password')) #if result is None: # raise #TODO find the exception this should raise # call the superclass to start the run loop -- it just sets # ._running to True and calls run, but let's not duplicate it. BackendBase.start(self) except: if getattr(self, "voice", None): self.voice.logout() raise def stop(self): # call superclass to stop--sets self._running # to False so that the 'run' loop will exit cleanly. BackendBase.stop(self) # logout from googlevoice if self.voice is not None: self.voice.logout()
class GoogleVoice (Buffers, Hotkey, Login, WebService): def __init__ (self, *args, **kwargs): self.gv = Voice() super (GoogleVoice, self).__init__(*args, **kwargs) self.login() def register_default_buffers (self): (_("Sms"), _("Voicemail"), _("Missed"), _("Received"), _("Placed")) self.register_buffer("Sms", buffers.Sms, announce=False) self.register_buffer("Voicemail", buffers.Voicemail, set_focus=False, announce=False) self.register_buffer("Missed", buffers.Missed, set_focus=False, announce=False) self.register_buffer("Received", buffers.Received, set_focus=False, announce=False) self.register_buffer("Placed", buffers.Placed, set_focus=False, announce=False) def do_login(self, *args, **kwargs): #self.wait_for_availability(url='https://www.google.com/voice', message=_("Unable to connect to Google Voice. %s will retry until connection is established.") % application.name) try: logging.debug("Logging into Google Voice.") self.gv.login(email=self.config['credentials']['email'], passwd=crypt.decrypt(self.config['credentials']['passwd'])) except LoginError: logging.exception("%s: Google Voice login failure." % self.name) return return True def login_succeeded (self): self.save_config() output.speak(_("Logged into Google Voice as %s") % self.config['credentials']['email']) def login_failed (self): output.speak(_("Unable to Log into Google Voice.")) self.login_required() def is_login_required (self): return not self.config['credentials']['email'] or not self.config['credentials']['passwd'] @always_call_after def login_required(self): if hasattr(sessions.current_session, 'frame'): frame = sessions.current_session.frame else: frame = self.frame dlg = gui.LoginDialog(parent=frame, title=_("Google Voice Login"), prompt=_("Please provide your credentials to login to Google Voice"), session=self) if dlg.ShowModal() == wx.ID_OK: self.config['credentials']['email'] = dlg.username.GetValue() self.config['credentials']['passwd'] = crypt.encrypt(dlg.password.GetValue()) dlg.Destroy() self.complete_login() def show_configuration_dialog(self): logging.debug("%s: displaying configuration dialog." % self.name) try: new = gui.configuration.GoogleVoiceConfigDialog(self.frame, wx.ID_ANY, config=self.config) new.SetDefaultValues() if new.ShowModal() == wx.ID_OK: with self.storage_lock: new.SetNewConfigValues() self.config['isConfigured'] = True output.speak(_("Configuration saved."), True) dispatcher.send(sender=self, signal=signals.config_saved) else: logging.debug("User canceled configuration. Exitting.") return output.speak(_("Configuration canceled."), True) except: logging.exception("%s: Unable to setup configuration dialog." % self.name) def shutdown (self, *args, **kwargs): self.gv.logout() super (GoogleVoice, self).shutdown(*args, **kwargs) def config_required (self): self.show_configuration_dialog() def source_numbers(self): answer = list() phones = self.gv.contacts.folder['phones'] for p in sorted(phones): if '@' not in phones[p]['formattedNumber']: answer.append(phones[p]['formattedNumber']) return answer def unformat_phone_number(self, number): """Given a string representation of a phone number, returns a long of the digits""" return int(''.join([c for c in number if ord(c) in xrange(48, 58)]))
def process_scores(img_name, db): score_re = re.compile("-?\d+\.?\d*") # login to gvoice and get sms voice = Voice(); logging.debug("Logging into Google Voice...") voice.login() logging.debug("Logged in successfully.\n") logging.debug("Retrieving SMS messages...") folder = voice.sms() logging.debug("SMS messages retrieved successfully.\n") print_bar = '----------------------------------------------' for msg in extractsms(voice.sms.html): text = msg['text'] sender = msg['from'] id = msg['id'] sendTimeStr = msg['time'] sendResponse = False # Check if the message is trash, or ours if (not text.startswith("Thank you")): logging.debug(print_bar) logging.debug('Processing message %s from %s'%(text, sender)) try: okayScore = False score = 0 try: score = float(score_re.search(text).group(0)) logging.debug('Read score: %s'%(score)) okayScore = (score is not None) and score >= db.minscore and score <= db.maxscore except: logging.debug("Couldn't parse score.") pass if okayScore: if db.add_score(img_name, user_score.Score(sender, score, id)): try: resp = get_thanks_reply(img_name, score) sendResponse = True except: print("Error while sending reply to %s for message '%s'.\n"%(sender, text)) else: resp = get_nothanks_reply(img_name, db.minscore, db.maxscore); sendResponse = True tFormat = '%I:%M %p' msgTime = dt.datetime.strptime(sendTimeStr, tFormat) nowT = dt.datetime.now() msgTime = dt.datetime(nowT.year, nowT.month, nowT.day, msgTime.hour, msgTime.minute, msgTime.second) tDiff = (nowT - msgTime) if sendResponse: if tDiff is not None and tDiff < MaxTimePass: do_respond(voice, sender, resp, id) else: logging.debug('Message too old. Not responding.') # Delete the message so we don't respond to it again logging.debug('Deleting message') voice._Voice__messages_post('delete', id, trash=1) except: print('Error processing message. "%s" from %s'%(text, sender)) logging.debug(print_bar) voice.logout() db.end_transaction()
class GVChat(Chat): """ Implements a google voice chat client. """ def __init__(self, user, password): self.gv = Voice() self.gv.login(user, password) self.to_phone = None self.to_name = None self.polltime = 30 self.step = 0 # fire immediately so that we have data to display Chat.__init__(self) self.register_event(1, self._update_poll_time) def status(self): """ Draw a fancy status bar displaying the person's name and phone number. """ if self.to_phone: phone = '(%s) %s - %s' % (self.to_phone[:3], self.to_phone[3:6], self.to_phone[6:]) else: phone = '' name = self.to_name if self.to_name else '' return ' poll in %ds | %s | %s ' % (self.step, name, phone) def _update_poll_time(self): if self.step == 0: self.getsms() self.step = self.polltime else: self.step -= 1 return True # always keep polling def getsms(self): """ Update the GVChat object with the first SMS thread in your SMS box. """ # We could call voice.sms() directly, but I found this does a rather # inefficient parse of things which pegs a CPU core and takes ~50 CPU # seconds, while this takes no time at all. data = self.gv.sms.datafunc() data = re.search(r'<html><\!\[CDATA\[([^\]]*)', data, re.DOTALL).groups()[0] divs = SoupStrainer('div') tree = BeautifulSoup(data, parseOnlyThese=divs) # We need to know who to send texts to, as that information is # not included with each message. msgtype = str(tree.find("span", attrs={"class": "gc-message-type"})) m = re.search('\((\d{3})\) (\d{3})-(\d{4})', msgtype) self.to_phone = ''.join(m.groups()) smses = [] # we only want the first conversation conversation = tree.find("div", attrs={"id" : True},recursive=False) msgs = conversation.findAll(attrs={"class" : "gc-message-sms-row"}) for row in msgs: msgitem = {"id" : conversation["id"]} spans = row.findAll("span", attrs={"class" : True}, recursive=False) for span in spans : cl = span["class"].replace('gc-message-sms-', '') msgitem[cl] = (" ".join(span.findAll(text=True))).strip() if msgitem["text"]: msgitem["text"] = BeautifulStoneSoup(msgitem["text"], convertEntities=BeautifulStoneSoup.HTML_ENTITIES ).contents[0] smses.append(msgitem) # Now that we have the SMSes, we can add their text and render them. self.curses_lock.acquire() # If smses is shorter than history, we started a new thread, so clear the # history. if len(smses) < len(self.history): self.history = [] self.chatscreen.clear() def sublist_index(haystack, needle): """ Find the starting index of a sublist in a list. Premature optimization is the root of all evil. The empty list is a sublist of every point in a list. """ try: for i in xrange(len(haystack)): if haystack[i:i+len(needle)] == needle: return i except IndexError: pass raise ValueError # only print new messages try: msgs = map(lambda m: m['from']+' '+m['text'], smses) idx = sublist_index(msgs, self.history) smses = smses[idx + len(self.history):] except ValueError: # if we didn't find anything, then print everything pass for sms in smses: name = sms["from"][:-1] if name != 'Me': self.to_name = name # if we're adding a message that's not from me, beep curses.beep() self.message(name, sms["text"]) self.curses_lock.release() def __exit__(self, type, value, traceback): self.gv.logout() Chat.__exit__(self, type, value, traceback) def send(self, msg): if not self.to_phone: raise ValueError("No phone number :-(") # BeautifulSoup chokes on some characters, and they will cause GVChat to # break until a new SMS thread is started. Typically, these characters # aren't in text messages, but they are easily accidentally pressed on the # keyboard. We remove them here and warn the user. for c in ']': if c in msg: msg = string.replace(msg, c, '') self.gv.send_sms(self.to_phone, msg) # We could use self.message() or wait until the next poll to alert the user # that we sent the message, but we might as well check for new messages # while we're sending. self.getsms()
paramDic['traderID'] = 'Justin Oliver' encodedParams = urllib.urlencode(paramDic) query = url + encodedParams # Send the alert print query response = urllib2.urlopen(query).read() # If we successfully completed a trade, send the text if response.lower().find('valid trade') >= 0 and response.lower().find('invalid trade') < 0 and debug == False: voice.login(personalEmail, password) voice.send_sms(JUSTINS_CELL, response) voice.send_sms(TYLERS_CELL, response) voice.send_sms(DANS_CELL, response) voice.logout() # Otherwise, we are finished looking else: break; # Get the latest email's timestamp result, data3 = mail.fetch(len(data[0].split()) - 1, 'INTERNALDATE') latestEmailTimestamp = time.mktime(imaplib.Internaldate2tuple(data3[0])) ## print email_message.items() # print all headers # ## Poll mailbox after alotted time time.sleep(1) except: print 'Error'
def send_winner(winner): voice = Voice() voice.login() voice.send_sms('3033246746', winner) voice.logout()
password = argv[2] except: print('Error! Please provide Passsword.') exit(0) try: voice.login(email, password) except: print('Error! Login failed.') exit(0) try: phoneNumber = re.sub(r'\D', '', argv[3]).lstrip('1') except: print('Error! Please provide a phone number') voice.logout() exit(0) try: text = json.loads(argv[4]) except: print('Error! Please provide a message') voice.logout() exit(0) try: voice.send_sms(phoneNumber, text) print('Message Sent') except: print('Error! Message not sent')
ignicks = [ _ for _ in args.ignore if 'nick_'+_ in data[':tags'] ] if len(ignicks) != 0: print "Message from ignored nick %s" % ignicks[0]; elif len(data[':tags']) == 0: print "No tags!"; else: # status was away and message wasn't from an ignored nick, so it's # safe to send if data[':type'] == 'private': msg = "%s: %s" % (data[':channel'], data[':message']); else: sender = ""; for _ in data[':tags']: if _[0:5] == 'nick_': sender = _[5:]; msg = "[%s %s] %s: %s" % (data[':server'], data[':channel'], sender, data[':message']); voice.send_sms(args.destination, msg); print "Message from %s" % msg.split(':')[0]; except KeyboardInterrupt: print "Goodbye!" voice.logout(); sys.exit(0); except: print "Error! [%s]" % data