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()
def run(): voice = Voice() voice.login() voice.sms() for msg in extractsms(voice.sms.html): print(msg)
def getSMS(queue): voice = Voice() print "logging in..." voice.login("*****@*****.**","ColdplaY1*") print "logged in..." while True: #sleep(60) voice.sms() tree = BeautifulSoup(voice.sms.html) unread = tree.find("div",attrs={"class":"goog-flat-button gc-message gc-message-unread gc-message-sms"}) try: thread = unread.find("div",attrs={"class":"gc-message-message-display"}) rows = thread.findAll("div",attrs={"class":"gc-message-sms-row"}) row=rows[len(rows)-1] sender = ''.join(row.find("span",attrs={"class":"gc-message-sms-from"})) if re.search("Watson",sender): message = ''.join(row.find("span",attrs={"class":"gc-message-sms-text"})).strip(' \t\r\n') message = "Sherlock "+message print 'putting',message queue.put(message) #indicate this came from sms queue.put("SMS") print 'marking as read' while True: folder = voice.search('is:unread') if folder.totalSize <= 0 : break for message in folder.messages: message.mark(1) print 'done marking as read' except: return
def get_sms_list(): voice = Voice() voice.login(email=Configuration.sms_user, passwd=Configuration.sms_password) voice.sms() sms_list = [] for msg in extractsms(voice.sms.html): sms_list.append(str(msg)) return sms_list
def main(): global voice #Google Voice Interface voice = Voice() voice.login(email,pwd) #Login while True: voice.sms() #Get SMS Data messages = extractSMS(voice.sms.html) #Get messages processMessages(messages) #Process Recieved Messages time.sleep(30)
def run(): received_messages = [] delay_time = 7 # time in seconds to wait between message checks response_message = "Hello Human! \n You will now receive the Zine Prologue. When finished, you may proceed to enter the Zine\n It works best with headphones. \n https://drive.google.com/file/d/1AKW5qbpcqbbVzaICtkejU0DBrW9HlIdb/view?usp=sharing" # your autoreply message voice = Voice() login(voice) # login will prompt for email/password in the command line print('Running...\nPress ctrl C to quit') while True: # get messages try: for msg in voice.sms().messages: if not msg.isRead: # log to the console print("{} >> {}".format(time.strftime('%x %X'), msg.phoneNumber)) # reply voice.send_sms(msg.phoneNumber, response_message) msg.mark(1) except KeyboardInterrupt: raise except: print("Unexpected error:", sys.exc_info()[0]) time.sleep(delay_time)
def run(): voice = Voice() voice.login() for msg in voice.sms().messages: if msg.phoneNumber == "+13145918660": msg.mark(0) print('marked')
def run(): voice = Voice() voice.login() for message in voice.sms().messages: if message.isRead: message.delete()
def handle_noargs(self, **options): voice = Voice() voice.login() smses = voice.sms() self.update_expired() for msg in extractsms(voice.sms.html): if len(msg["from"]) == 0: continue if msg["from"] == "Me:": continue TextMsg.objects.create(text = msg["text"], from_number = msg["from"], start_time = datetime.now()) for message in voice.sms().messages: message.delete() texts=TextMsg.objects.filter(status=0) for m in texts: m.status = 1 m.save() msg={} msg["from"] = m.from_number msg["text"] = m.text try: self.test_handle(msg) sms_logger.info("success: %s" % msg) m.status = 2 m.end_time = datetime.now() m.save() except CommandError: continue except ObjectDoesNotExist, e: sms_logger.exception ("\"%s\" causes an error:" % msg) continue except MultipleObjectsReturned, e: sms_logger.exception ("\"%s\" causes an error:" % msg) continue
class Poller(object): """ @summary: Polls Google Voice looking for new texts """ def __init__(self): self.voice = Voice() self.voice.login() def poll(self): numbers = [] inBox = self.voice.sms() for msg in inBox.messages: if not msg.isRead: numbers.append(msg.phoneNumber) msg.mark(read=1) return numbers
def handle_noargs(self, **options): voice = Voice() voice.login() smses = voice.sms() to_be_deleted = [] for msg in extractsms(voice.sms.html): if msg["from"] != "Me": print msg sender_number = parse_phone_number(msg["from"]) if sender_number: answerer = map_number_to_user(sender_number) if not answerer: continue id, body = parse_question_id(msg["text"]) print "id: %s" % str(id) if not id: continue print "body: %s" % str(body) try: question = Question.objects.get(pk=id) # A few checks here if not body: print "answer is empty" continue if not question.answerable(): print "answer is answerable" continue if question.asker == answerer: print "Asker is the same as the answerer" continue if question.is_answered_by(answerer): answer = Answer.objects.get(question=question, answerer=answerer) answer.answer_text = answer.answer_text + "\n" + body answer.edit_time_stamp = datetime.now() else: answer = Answer(answerer=answerer, question=question, time_stamp=datetime.now(), answer_text=body) answer.save() to_be_deleted.append(msg["id"]) except Exception, e: print e
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()
if (msglen == counter) : break elif msgfolder == "Voicemail" : msglen = len(voice.voicemail().messages) for message in voice.voicemail().messages: counter = doactions(counter, ACTION, message.id , ID) if (msglen == counter) : break elif msgfolder == "Recorded" : msglen = len(voice.recorded().messages) for message in voice.recorded().messages: counter = doactions(counter, ACTION, message.id , ID) if (msglen == counter) : break elif msgfolder == "Messages" : msglen = len(voice.sms().messages) for message in voice.sms().messages: counter = doactions(counter, ACTION, message.id , ID) if (msglen == counter) : break elif msgfolder == "All" : voice.all() folder = voice.all.folder msglen = len(folder.messages) for message in folder.messages: counter = doactions(counter, ACTION, message.id , ID) if (msglen == counter) : break elif msgfolder == "Placed" : msglen = len(voice.placed().messages) for message in voice.placed().messages:
Output is a list of dictionaries, one per message. """ msgitems = [] # accum message items here # Extract all conversations by searching for a DIV with an ID at top level. tree = BeautifulSoup.BeautifulSoup(htmlsms) # parse HTML into tree conversations = tree.findAll("div", attrs={"id": True}, recursive=False) for conversation in conversations: # For each conversation, extract each row, which is one SMS message. rows = conversation.findAll(attrs={"class": "gc-message-sms-row"}) for row in rows: # for all rows # For each row, which is one message, extract all the fields. msgitem = { "id": conversation["id"] } # tag this message with conversation ID spans = row.findAll("span", attrs={"class": True}, recursive=False) for span in spans: # for all spans in row cl = span["class"].replace('gc-message-sms-', '') msgitem[cl] = (" ".join( span.findAll(text=True))).strip() # put text in dict msgitems.append(msgitem) # add msg dictionary to list return msgitems voice = Voice() voice.login() voice.sms() for msg in extractsms(voice.sms.html): print str(msg)
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()
from googlevoice import Voice voice = Voice() voice.login() for message in voice.sms().messages: if message.isRead: message.delete()
assert credentials['email'] assert credentials['password'] voice = Voice() voice.login( credentials['email'], credentials['password'] ) # leave out the arguments to make it ask each time so you don't have your password floating around in plain text. header = ('id', 'phone', 'date', 'time', 'from', 'text') conversations = [] page = 0 dtdate = datetime.date cont = True while cont: page += 1 voice.sms(page) count = 0 for conv in nextConversation(voice.sms.data, voice.sms.html): count += 1 startTime = conv['startTime'].encode( "utf-8" ) #not really "start" time it's actually "last message received at" time, but start is shorter phoneNumber = conv['phoneNumber'].encode("utf-8") floatTime = float(startTime) / 1000.0 date = dtdate.fromtimestamp(floatTime).strftime('%Y-%m-%d').encode( 'utf-8') compareTime = datetime.datetime.fromtimestamp(floatTime) item = 0 #if starttime is less than lastRTStamp then break cause these messages were got last time this was run if compareTime < lastRTStamp: cont = False
def main(): # wake up andrew Andrew = Personality("andrew") Andrew.learn() # set verbosity flag for debugging purposes verbose = True # get logfile records = "/rec.db" logfile = "/log.db" # instantiate gvoice object voice = Voice() voice.login() # grab the SMS messages voice.sms() # loop through messages for msg in extractsms(voice.sms.html): print print(msg) hash = hashlib.md5() hash.update(msg['text'] + msg['time']) key = hash.hexdigest() print("Unique hash: " + key) # check if this is in log file duplicate = False f = open(logfile, "a+") for line in f: if key in line: duplicate = True if verbose: print("Duplicate: " + str(duplicate)) # if this is a duplicate, continue if duplicate: f.close() continue # if its FROM me, continue if "Me" in msg['from']: print("Skipping messages from me.") f.close() continue # else add to log else: e = open(records, "a+") e.write("\n") e.write(str(msg)) e.write("\n") f.write(key + "-") f.close() # print convo text = msg['text'] if verbose: print(msg['from'] + ": \"" + text + "\"") response = Andrew.converse(text) if verbose: print("Andrew: " + str(response)) e.write(str(response) + "\n") try: # send response SMS voice.send_sms(msg['from'], str(response)) except Exception as e: print(e) for message in voice.sms().messages: message.delete()
class MessageListener(): def __init__(self, refresh_interval=30): """ * refresh_interval is in seconds """ self.voice = Voice() self.voice.login() sms = self.voice.sms() html = self.voice.sms.html_data self.conversations = self.getConversations(self.voice) or self.conversations # this in case it fails because of an image or something self.last_message_count = self.voice.sms.data['totalSize'] while True: self.loop() sleep(refresh_interval) def get_unread_count(self, folder): unread_count = 0; i = 0 while True: try: if not folder.messages[i].isRead: print(read_message(self.voice, i)) unread_count += 1 i += 1 except IndexError: break return unread_count def getConversations(self, voice): try: sms = voice.sms() except googlevoice.util.ParsingError: return None conversations = {} i = 0 while True: try: contact_name = voice.sms.html_data.find(id=sms.messages[i].id) message_data = sms.messages[i] try: contact_name = contact_name.find('span', class_='gc-message-name').find('a').text except: contact_name = contact_name.find('span', class_='gc-message-name').select('span[title]')[0].attrs['title'] raw_messages = voice.sms.html_data.find(id=sms.messages[i].id).select('.gc-message-sms-row') try: from_number = voice.sms.html_data.find(id=sms.messages[i].id).find('span', class_='gc-message-type').text except AttributeError: from_number = voice.sms.html_data.find(id=sms.messages[i].id).find('span', class_='gc-message-name').text from_number = re.search(r'([\(\)\s\-\d]+\d)', from_number).group(0) messages = [] for message in raw_messages: from_ = message.find('span', class_='gc-message-sms-from').text.strip()[:-1] text = message.find('span', class_='gc-message-sms-text').text time = message.find('span', class_='gc-message-sms-time').text.strip() txt = Text(from_=from_, from_number=from_number, text=text, time=time, isRead=message_data.isRead) messages.append(txt) if contact_name in conversations.keys(): conversations[contact_name] += messages else: conversations[contact_name] = messages i += 1 except IndexError: break return conversations def loop(self): sms = self.voice.sms() updated_conversations = self.getConversations(self.voice) new_message = False new_messages = [] if len(updated_conversations.keys()) > len(self.conversations.keys()): new_message = True #print("new conversation") elif len(updated_conversations.keys()) == len(self.conversations.keys()): #print("same # of conversations") for contact in self.conversations.keys(): last_messages = self.conversations[contact] updated_messages = updated_conversations[contact] if len(updated_messages) > len(last_messages): new_message = True #print("new message") for i in range(0, len(updated_messages)): #print(len(last_messages),len(updated_messages),i) try: if last_messages[i].text == updated_messages[i].text: continue elif last_messages[i-1].text == updated_messages[i].text: continue elif last_messages[i+1].text == updated_messages[i].text: continue else: # this updated_message must be a new one--it doesn't appear to be in the last_messages new_messages.append(updated_messages[i]) except IndexError: if last_messages[i-2].text == updated_messages[i].text: continue elif last_messages[i-1].text == updated_messages[i].text: continue elif last_messages[0].text == updated_messages[i].text: continue else: # this updated_message must be a new one--it doesn't appear to be in the last_messages new_messages.append(updated_messages[i]) self.conversations = updated_conversations for msg in new_messages: if msg.from_ != 'Me': # TODO: only send the auto-response if the last message was more than 30 minutes ago print("New message! => %s" % msg.toString()) dumb_contacts = ['Aimee Hudson', 'Andrew Post'] test_contacts = ['Drew Meier', '17246673655'] if msg.from_ in dumb_contacts: self.voice.send_sms(msg.from_number, "You're dumb") if msg.from_ in test_contacts or msg.from_number in test_contacts: self.voice.send_sms(msg.from_number, "Auto-reply from megatron. Let me know if you get this (it doesn't show up on my chat).")
from googlevoice import Voice voice = Voice() voice.login() for i in xrange(50): for message in voice.sms().messages: #if message.isRead: message.delete()
credentials = json.load(file('gmail-credentials.js')) assert credentials['email'] assert credentials['password'] voice = Voice() voice.login(credentials['email'], credentials['password']) # leave out the arguments to make it ask each time so you don't have your password floating around in plain text. header = ('id', 'phone', 'date', 'time', 'from', 'text') conversations = [] page = 0 dtdate = datetime.date cont = True while cont: page += 1 voice.sms(page) count = 0 for conv in nextConversation(voice.sms.data, voice.sms.html): count += 1 startTime = conv['startTime'].encode("utf-8") #not really "start" time it's actually "last message received at" time, but start is shorter phoneNumber = conv['phoneNumber'].encode("utf-8") floatTime = float(startTime) / 1000.0 date = dtdate.fromtimestamp(floatTime).strftime('%Y-%m-%d').encode('utf-8') compareTime = datetime.datetime.fromtimestamp(floatTime) item = 0 #if starttime is less than lastRTStamp then break cause these messages were got last time this was run if compareTime < lastRTStamp: cont = False break messages = conv['messages'] for message in messages:
im_passwd = getpass.getpass("Jabber account password: "******"Account to send message to (for gmail, INCLUDE @gmail.com): ") client = xmpp.Client('gmail.com',debug=[]) client.connect(server=('talk.google.com',5223)) client.auth(im_username,im_passwd, 'botty') client.sendInitPresence() first = True sms_count = {} # repeat the following loop until the program is killed while True: # first find out how many unread messages there are allsms = voice.sms() new_sms = allsms['unreadCounts']['sms'] smss = allsms['messages'] found = 0 # iterate through unread sms messages, keeping track of what notifications have been sent. # it's a bit tricky to keep track of what's really new since # an unread sms thread may contain more than 1 new message since the last iteration, though google # voice only reports one unread message (i.e. just that there are new messages in that thread) # thus for each thread you have, this keeps track of how many messages there were at # the previous iteration and notifies you of all new messages since if first: sms_parse = BeautifulSoup(voice.sms_html()) else: if new_sms>0:
im_passwd = getpass.getpass("Jabber account password: "******"Account to send message to (for gmail, INCLUDE @gmail.com): ") client = xmpp.Client('gmail.com', debug=[]) client.connect(server=('talk.google.com', 5223)) client.auth(im_username, im_passwd, 'botty') client.sendInitPresence() first = True sms_count = {} # repeat the following loop until the program is killed while True: # first find out how many unread messages there are allsms = voice.sms() new_sms = allsms['unreadCounts']['sms'] smss = allsms['messages'] found = 0 # iterate through unread sms messages, keeping track of what notifications have been sent. # it's a bit tricky to keep track of what's really new since # an unread sms thread may contain more than 1 new message since the last iteration, though google # voice only reports one unread message (i.e. just that there are new messages in that thread) # thus for each thread you have, this keeps track of how many messages there were at # the previous iteration and notifies you of all new messages since if first: sms_parse = BeautifulSoup(voice.sms_html()) else: if new_sms > 0: sms_parse = BeautifulSoup(voice.sms_html())
rows = conversation.findAll(attrs={"class" : "gc-message-sms-row"}) for row in rows : # for all rows # For each row, which is one message, extract all the fields. msgitem = {"id" : conversation["id"]} # tag this message with conversation ID spans = row.findAll("span",attrs={"class" : True}, recursive=False) for span in spans : # for all spans in row cl = span["class"].replace('gc-message-sms-', '') msgitem[cl] = (" ".join(span.findAll(text=True))).strip() # put text in dict msgitems.append(msgitem) # add msg dictionary to list return msgitems #Main Event Loop voice = Voice() voice.login() voice.sms() msgs = extractsms(voice.sms.html) try: msg = msgs[len(msgs)-1] except IndexError as e: print "no messages to check right now." msg = [] key = "" if isSMScommand(msg): key = getSmsCommandKey(msg) pin = sendVerifyText(msg) verifyReceivedPin(5*60,pin,msg)
class googleVoice: #The authorized numbers, as well as their corresponding names, and text responses authorizedNumbers = config.authorizedNumbers names = config.names textResponses = [ "Garage is closed", "Garage is Open. Would you like to close it? (Y/N)", """Please only send messages once every 10 seconds. If no immediate response, please wait 30 seconds. Thank you! Commands: Status - Ask if garage is opened or closed Close - Closes the garage Open - Opens the garage""", "Please enter a valid command. A list of commands is given by typing Help.", "Ok garage closing now.", "Garage will remain open", "J.A.R.V.I.S is now shutting down.", "Incorrect response. Would you like to close garage? (Y/N)", "Garage door is closed", "Garage door is already closed", "Garage door is already opened", "Ok garage opening now" ] #Password to shutdown program __shutdownPassword = "******" def __init__(self, usrName, pswd): global logger_googleVoice self.usrName = usrName self.pswd = pswd self.voice = Voice() self.numReceivedFrom = [] self.messageReceived = [] try: self.voice.login(self.usrName, self.pswd) logger_googleVoice.info("Successfully logged into Google Voice") except: logger_googleVoice.exception("Unable to login into Google Voice") exit(0) self.__markAsRead() self.__deleteMessages() self.__readyNotify() self.phoneToSend = "" print("Startup complete") def __readyNotify(self): """readyMessage = "J.A.R.V.I.S ready to receive commands." for num in googleVoice.authorizedNumbers: self.__sendMessage(num,readyMessage)""" num = googleVoice.authorizedNumbers[1] person = googleVoice.names[num] readyMessage = "Hello " + person + ", J.A.R.V.I.S is ready to receive commands." self.__sendMessage(num, readyMessage) def __receiveSMS(self): global logger_googleVoice self.voice.sms() while True: self.numReceivedFrom = [] self.messageReceived = [] self.__extractSMS((self.voice.sms.html)) if len(self.numReceivedFrom) > 0: break time.sleep(2) print("Got messages") if len(self.numReceivedFrom) != len(self.messageReceived): exit(1) recentMess = self.messageReceived[0] if self.__passwordCheck(recentMess): recentMess = "***************************" mess = "From " + self.numReceivedFrom[0] + ": " + recentMess logger_googleVoice.debug(mess) return def __extractSMS(self, htmlsms): """ extractsms -- extract SMS messages from BeautifulSoup tree of Google Voice SMS HTML. """ rawMessage = BeautifulSoup(htmlsms, "html.parser") # parse HTML into tree self.__markAsRead() text = rawMessage.get_text() #remove HTML Tags text = text.strip() #remove extra whitespace newText = re.sub(r'[\r\n][\r\n]{2,}', '\n\n', text) #remove extra newlines giantList = newText.splitlines() #put each line into a list pos = 0 lenList = len(giantList) while True: if pos >= lenList: #only run the loop for the length of the list break curr = giantList[pos] authorized, phoneNum = self.__isAuthorizedNumber( curr ) #see if there is a text message from any of the authorized numbers if authorized: self.numReceivedFrom.append( phoneNum) #Keep track of who sent a message pos = pos + 2 cleanText = self.__cleanMessage( giantList[pos] ) #The message received is two lines below the number self.messageReceived.append(cleanText) continue pos = pos + 1 def __isAuthorizedNumber(self, numberString): """Checks the list entries above to see if they are the authorized numbers.""" for i in range(0, len(googleVoice.authorizedNumbers)): num = googleVoice.authorizedNumbers[i] testString = num + ":" if testString in numberString: return True, num return False, -3 def __cleanMessage(self, message): phone = "" stringLength = len(message) for i in range(0, stringLength): testChar = message[i] if testChar.isalnum(): #print(testChar) For testing phone = phone + testChar elif testChar.isspace(): if i == (stringLength - 1): continue elif len(phone) == 0: continue else: phone = phone + testChar else: continue return phone def __markAsRead(self): for message in self.voice.sms().messages: message.mark(1) def __deleteMessages(self): listMess = self.voice.sms().messages for message in listMess: if message.isRead: message.delete() print("Finish deleting messages") logger_googleVoice.info("All messages deleted") def __sendMessage(self, phoneNum, txtmsg): global logger_googleVoice try: self.voice.send_sms(phoneNum, txtmsg) self.__deleteMessages() loggingMess = "Sent: " + txtmsg + " to " + phoneNum + "." except: loggingMess = "Error. Message not sent to " + phoneNum + "." logger_googleVoice.debug(loggingMess) def __interpretDefaultMessage(self, inputMessage): """1 = continue conversation. 0 = end conversation """ global door1 message = inputMessage.lower() # Format : Response, continue conversation, close/open garage (0=no,1=close,2=open) if message == "status": if door1.status() == "closed": return googleVoice.textResponses[8], 0, 0 else: return googleVoice.textResponses[1], 1, 1 elif message == "help": return googleVoice.textResponses[2], 0, 0 elif message == "close": if door1.status() == "closed": return googleVoice.textResponses[9], 0, 0 else: return googleVoice.textResponses[4], 0, 1 elif message == "open": if door1.status() == "opened": return googleVoice.textResponses[10], 0, 0 else: return googleVoice.textResponses[11], 0, 2 elif message == "vacation mode on": mess = vacationMode(True, self.phoneToSend) return mess, 0, 0 elif message == "vacation mode off": mess = vacationMode(False, self.phoneToSend) return mess, 0, 0 elif message == "shut down": mess, passfound = self.__shutDownProcess() if passfound == 2: self.__sendMessage(self.phoneToSend, mess) exit(3) return mess, 0, False else: return googleVoice.textResponses[3], 0, False def __interpretCloseGarageMessage(self, inputMessage): global door1 message = inputMessage.lower() retMessage = "" closeGar = False while True: if message == "y": retMessage = googleVoice.textResponses[4] closeGar = True break elif message == "n": retMessage = googleVoice.textResponses[5] break else: self.__sendMessage(self.phoneToSend, googleVoice.textResponses[7]) time.sleep(3) self.__receiveSMS() message = self.messageReceived[0].lower() return retMessage, closeGar def __passwordCheck(self, password): if password == googleVoice.__shutdownPassword: return True else: return False def __shutDownProcess(self): global logger_googleVoice print("Super Shut down") cnt = 0 wrongPass = "******" messToSend = "" foundPass = 0 while True: if cnt == 0: print("Please Enter Password") print(self.phoneToSend) self.__sendMessage(self.phoneToSend, "Please enter password:"******"Ay Tanga! Too many failed attempts. Exiting shutdown procedure. Resuming normal function." print(messToSend) logger_googleVoice.info( "Shut down process failed. Too many failed password attempts." ) break else: inCorrectTxt = wrongPass + " Attempt " + str( cnt) + " out of 3 attempts." self.__sendMessage(self.phoneToSend, inCorrectTxt) self.__receiveSMS() if self.__passwordCheck(self.messageReceived[0]): messToSend = "Password accepted" + ". " + googleVoice.textResponses[ 6] foundPass = 2 logger_googleVoice.info( "Shut down process completed. Correct password found.") break else: cnt = cnt + 1 print(cnt) print(messToSend) return messToSend, foundPass def unReadMessages(self): global logger_googleVoice try: numUnread = len(self.voice.sms().messages) return numUnread except: logger_googleVoice.exception("Failed to find unread messages") def sms(self, phonenum, message): self.__sendMessage(phonenum, message) def getCommands(self): global door1 while True: defaultMessageState = 0 self.__receiveSMS() if len(self.numReceivedFrom) != len(self.messageReceived): exit(1) self.phoneToSend = self.numReceivedFrom[0] txtmsg, contConvo, closeGarage = self.__interpretDefaultMessage( self.messageReceived[0]) while True: if contConvo == 0: self.__sendMessage(self.phoneToSend, txtmsg) if closeGarage == 1: door1.closeDoor("close") elif closeGarage == 2: door1.closeDoor("open") break elif contConvo == 1: print(self.phoneToSend, " ", txtmsg) self.__sendMessage(self.phoneToSend, txtmsg) time.sleep(3) self.__receiveSMS() txtmsg, closeGarage = self.__interpretCloseGarageMessage( self.messageReceived[0]) self.__sendMessage(self.phoneToSend, txtmsg) if closeGarage == True: door1.closeDoor() break elif contConvo == 2: self.__sendMessage(self.phoneToSend, txtmsg) print("Received shut down input ") exit(2) print("Done") break
class GoogleVoiceManager: ### This whole f*****g thing is deprecated. The "API" is shit, and Twilio is infinitely better. def __init__(self): self.voice = Voice() self.voice.login(GOOGLE_VOICE['username'], GOOGLE_VOICE['password']) def send_message(self, to, message): try: return self.voice.send_sms(to, message) except: print "BOOP. There was a problem sending the sms notification." return False def extractsms(self): """ extractsms -- extract SMS messages from BeautifulSoup tree of Google Voice SMS HTML. Output is a list of dictionaries, one per message. Ported from code by John Nagle ([email protected]) """ self.voice.sms() htmlsms = self.voice.sms.html msgitems = [] # accum message items here # Extract all conversations by searching for a DIV with an ID at top level. tree = BeautifulSoup.BeautifulSoup(htmlsms) # parse HTML into tree conversations = tree.findAll("div", attrs={"id" : True}, recursive=False) for conversation in conversations : # For each conversation, extract each row, which is one SMS message. rows = conversation.findAll(attrs={"class" : "gc-message-sms-row"}) for row in rows : # for all rows # For each row, which is one message, extract all the fields. msgitem = {"id" : conversation["id"]} # tag this message with conversation ID spans = row.findAll("span", attrs={"class" : True}, recursive=False) for span in spans : # for all spans in row cl = span["class"].replace('gc-message-sms-', '') msgitem[cl] = (" ".join(span.findAll(text=True))).strip() # put text in dict msgitems.append(msgitem) # add msg dictionary to list return [msg for msg in msgitems if msg['from'] != u'Me:'] def get_new_schedule_messages(self): smses = self.extractsms() new_smses = [] for sms in smses: sms['text'] = sms['text'].lower() if sms['text'].startswith('add schedule '): query = "SELECT guid FROM EpisodeSchedule WHERE sms_guid = %(sms_guid)s" if DatabaseManager().fetchone_query_and_close(query, {'sms_guid': hashlib.md5(sms['text']).hexdigest()}) is None: #example sms: # {u'text': u'Poop', u'from': u'+14132976806:', 'id': u'd4f1ef49f44625f912e0ee757483ac3fb19d2a41', u'time': u'1:57 PM'} sch = {} sch['phone'] = sms['from'].split('+1')[1][:-1] sch['user'] = UserManager().get_user_id_by_phone(sch['phone']) sch['sms_guid'] = hashlib.md5(sms['text']).hexdigest() if sms['text'].split('add schedule ')[1].split(' ')[0].upper() == 'TV': sch['type'] = 'Episode' elif sms['text'].split('add schedule ')[1].split(' ')[0].upper() == 'MOVIE': sch['type'] = 'Movie' sch['name'] = sms['text'].split('add schedule ')[1].split(' ', 1)[1] new_smses.append(sch) return new_smses def get_on_demand_movies(self): smses = self.extractsms() new_smses = [] for sms in smses: sms['text'] = sms['text'].lower() if sms['text'].startswith('add movie '): query = "SELECT guid FROM OnDemandSMS WHERE sms_guid = %(sms_guid)s" if DatabaseManager().fetchone_query_and_close(query, {'sms_guid': hashlib.md5(sms['text']).hexdigest()}) is None: #example sms: # {u'text': u'Poop', u'from': u'+14132976806:', 'id': u'd4f1ef49f44625f912e0ee757483ac3fb19d2a41', u'time': u'1:57 PM'} mov = {} mov['phone'] = sms['from'].split('+1')[1][:-1] mov['user'] = UserManager().get_user_id_by_phone(mov['phone']) mov['sms_guid'] = hashlib.md5(sms['text']).hexdigest() mov['search'] = sms['text'].split('add movie ')[1] new_smses.append(mov) return new_smses
except: print ('Error! Login failed. ') exit(0) try: command = argv[3] except: print ('Error! Please provide a phone number or FOLDER. ') voice.logout() exit(0) if command == "Inbox" : folder = voice.inbox().messages foundmsg = [ msg for msg in folder] elif command == "Messages" : folder = voice.sms().messages foundmsg = [ msg for msg in folder] elif command == "All" : voice.all() folder = voice.all.folder foundmsg = [ msg for msg in folder.messages] elif command == "Spam" : voice.spam() folder = voice.spam.folder foundmsg = [ msg for msg in folder.messages] elif command == "Trash" : voice.trash() folder = voice.trash.folder foundmsg = [ msg for msg in folder.messages] elif command == "Placed" : folder = voice.placed().messages
from googlevoice import Voice,util from BeautifulSoup import BeautifulSoup import urllib2 import urllib import re import time import string while True: voice = Voice() print "logging in..." voice.login('***gmail****', ******'gmail password******') newMessage=False voiceRequest=False smsRequest=False if len(voice.sms().messages)>0: newMessage=True print "woohoo! sms!" sms_parse=BeautifulSoup(voice.sms_html()) extractedText=sms_parse.find(attrs={"class":"gc-message-sms-text"}); extractedSMSNumber=sms_parse.find(attrs={"class":"gc-message-sms-from"}); HTMLtag = re.compile('<.*?>') # Matches HTML tags HTMLcom = re.compile('<!--.*?-->') # Matches HTML comments extractedText = HTMLtag.sub('', HTMLcom.sub('', str(extractedText))) extractedSMSNumber = HTMLtag.sub('', HTMLcom.sub('', str(extractedSMSNumber))) extractedSMSNumber=extractedSMSNumber.strip(); extractedSMSNumber=extractedSMSNumber.replace(":",""); extractedSMSNumber=extractedSMSNumber.replace("(",""); extractedSMSNumber=extractedSMSNumber.replace(")",""); extractedSMSNumber=extractedSMSNumber.replace("-",""); extractedSMSNumber=extractedSMSNumber.replace(" ","");
class Sms(Thread): """Check SMS messages from a Google Voice account to control the lightshow When executed, this script will check all the SMS messages from a Google Voice account checking for either the "help" command, which will cause a help message to be sent back to the original sender, or a single number indicating which song they are voting for. When a song is voted for, the playlist file will be updated with the sender's cell phone number to indicate it has received a vote from that caller. This also enforces only a single vote per phone number per s (until that song is played). See the commands.py file for other commands that are also supported (as well as instructions on adding new own commands). Sample usage: sudo python check_sms.py --playlist=/home/pi/music/.playlist For initial setup: sudo python check_sms.py --setup=True Third party dependencies: pygooglevoice: http://sphinxdoc.github.io/pygooglevoice/ Beautiful Soup: http://www.crummy.com/software/BeautifulSoup/ """ def __init__(self, setup=False): super(Sms, self).__init__() self.daemon = True self.cancelled = False if setup: self.cancelled = True # if not using sms exit if not cm.sms.enable: self.cancelled = True sys.exit() levels = { 'DEBUG': logging.DEBUG, 'INFO': logging.INFO, 'WARNING': logging.WARNING, 'ERROR': logging.ERROR, 'CRITICAL': logging.CRITICAL } # set logging level from config or command line if used try: level = levels.get(args.log.upper(), logging.NOTSET) except NameError: level = levels.get(cm.sms.log_level, logging.NOTSET) logging.getLogger().setLevel(level) try: self.playlist = args.playlist except NameError: self.playlist = cm.sms.playlist_path self.songs = list() logging.info('loading playlist ' + self.playlist) self.load_playlist() commands.start(cm) self.voice = Voice() def run(self): """Overloaded Thread.run, runs the update method once per every 15 seconds.""" self.login() while not self.cancelled: try: self.update() except: logging.error( 'Error when checking for sms messages, will try again in 15 seconds.', exc_info=1) time.sleep(15) def cancel(self): """End this timer thread""" self.cancelled = True def update(self): """Check for new messages""" self.check() def login(self): """Login to google voice account Setup your username and password in ~/.gvoice (or /root/.gvoice when running as root) file as follows to avoid being asked for your email and password each time: [auth] email=<google voice email address> password=<google voice password> """ # make sure we are logged in # if unable to login wait 30 seconds and try again # if unable to login after 3 attempts exit check_sms logged_in = False attempts = 0 while not logged_in: try: self.voice.login() logged_in = True logging.info("Successfully logged in to Google Voice account") except LoginError as error: attempts += 1 if attempts <= 3: time.sleep(30) else: logging.critical( 'Unable to login to Google Voice, Exiting SMS.') self.cancelled = True sys.exit() @staticmethod def extract_sms(html_sms): """Extract SMS messages from BeautifulSoup tree of Google Voice SMS Html, returning a list of dictionaries, one per message. extract_sms - taken from http://sphinxdoc.github.io/pygooglevoice/examples.html originally written by John Nagle ([email protected]) :param html_sms: Google Voice SMS Html data :type html_sms: BeautifulSoup object :return: msg_items :rtype: dictionary """ msgitems = [] # parse HTML into tree tree = BeautifulSoup(html_sms) conversations = tree.findAll("div", attrs={"id": True}, recursive=False) for conversation in conversations: # For each conversation, extract each row, which is one SMS message. rows = conversation.findAll(attrs={"class": "gc-message-sms-row"}) # for all rows for row in rows: # For each row, which is one message, extract all the fields. # tag this message with conversation ID msgitem = {"id": conversation["id"]} spans = row.findAll("span", attrs={"class": True}, recursive=False) # for all spans in row for span in spans: name = span['class'].replace('gc-message-sms-', '') # put text in dict msgitem[name] = (" ".join(span.findAll(text=True))).strip() # add msg dictionary to list msgitems.append(msgitem) return msgitems def load_playlist(self): """ Load playlist from file notifying users of any of their requests that are now playing """ with open(self.playlist, 'rb') as playlist_fp: fcntl.lockf(playlist_fp, fcntl.LOCK_SH) playlist = csv.reader(playlist_fp, delimiter='\t') self.songs = list() for song in playlist: logging.debug(song) if len(song) < 2 or len(song) > 4: logging.error( 'Invalid playlist. Each line should be in the form: ' '<song name><tab><path to song>') logging.warning('Removing invalid entry') print "Error found in playlist" print "Deleting entry:", song continue elif len(song) == 2: song.append(set()) elif len(song) >= 3: # Votes for the song are stored in the 3rd column song[2] = set(song[2].split(',')) if len(song) == 4: # Notification of a song being played is stored in the 4th column # Send an sms message to each requesting user that their song is now playing for phonenumber in song[2]: self.voice.send_sms( phonenumber, '"' + song[0] + '" is playing!') del song[3] song[2] = set() self.songs.append(song) fcntl.lockf(playlist_fp, fcntl.LOCK_UN) logging.info('loaded %d songs from playlist', len(self.songs)) cm.set_playlist(self.songs) def update_playlist(self): """Update playlist with latest votes""" with open(self.playlist, 'wb') as playlist_fp: fcntl.lockf(playlist_fp, fcntl.LOCK_EX) writer = csv.writer(playlist_fp, delimiter='\t') for song in self.songs: if len(song[2]) > 0: song[2] = ",".join(song[2]) else: del song[2] writer.writerows(self.songs) fcntl.lockf(playlist_fp, fcntl.LOCK_UN) def check(self): """Process sms messages Download and process all sms messages from a Google Voice account. this is executed every 15 seconds """ # load the playlist self.load_playlist() # Parse and act on any new sms messages messages = self.voice.sms().messages for msg in self.extract_sms(self.voice.sms.html): logging.debug(str(msg)) response = commands.execute(msg['text'], msg['from']) if response: logging.info('Request: "' + msg['text'] + '" from ' + msg['from']) try: if isinstance(response, basestring): self.voice.send_sms(msg['from'], response) else: # Multiple parts, send them with a delay in hopes to avoid # them being received out of order by the recipient. for part in response: self.voice.send_sms(msg['from'], str(part)) time.sleep(2) except ValidationError as v_error: logging.warn( str(v_error) + ': Error sending sms response (command still executed)', exc_info=1) logging.info('Response: "' + str(response) + '"') else: logging.info('Unknown request: "' + msg['text'] + '" from ' + msg['from']) self.voice.send_sms(msg['from'], cm.sms.unknown_command_response) # update the playlist self.update_playlist() # Delete all messages now that we've processed them for msg in messages: msg.delete(1)
def show_user_cards (phenny, input): unobot.showCards (phenny, input.nick) show_user_cards.commands = ['cards'] ''' # ====================================================================== # Log into Google Voice voice = Voice() voice.login() # Keep searching all messages for a '.uno' k=True while k==True: voice.sms() # Search text messages for '.uno' and just '.uno' for each in extractsms(voice.sms.html): # act accordingly. input = each["from"] if input != "Me:": a = input[1:-1] if each["text"] == '.uno' and voice.sms().messages[0].isRead == False: print "Starting the game!" unobot.start (a) break elif each["text"] == 'join': print "Joining " + str(a) + " to the game!" unobot.join(a) break elif each["text"] == 'deal':