My main comment is that you should separate the different concerns of you code into descriptive functions. This will make it a lot more readable (and re-usable). One comment before I get started: Your `login` function, which looks like it would log you in with the reddit API seems to be unused atm. I guess this is a copy&paste error from censoring? ---------- Your first concern is to log-in with gmail to get the `mail` object. This can be pasted directly into a separate function: def mail_login(): mail = imaplib.IMAP4_SSL('imap.gmail.com') while True: try: emailpass = getpass.getpass( 'Please enter the password for xxxxxxx@xxxxx: ') mail.login('[email protected]', emailpass) break except imaplib.IMAP4.error: print('Incorrect password') mail.select("inbox") return mail ---------- The second task, which is repeated quite often, is to print a message with the current timestamp preceeding it: def log(text): print('\t{:%Y-%m-%d %H:%M:%S} - {}'.format(datetime.now(), text)) Note that I used the custom format options of `str.format` here. ---------- Another task is to post an alert to reddit, once it is found: def post_alert(alert, r): alert_text = """ {} ******** *^^I ^^am ^^a ^^bot. ^^For ^^any ^^questions, ^^comments, ^^or ^^concerns, ^^please ^^email [^^xxxxxxx@xxxxx](mailto://xxxxxxx@xxxxx)* """ while True: try: r.submit(subreddit='xxxxxxxxxxxx', title=alert, text=alert_text.format(alert)) print('\t{}'.format(alert), end=' ') break except praw.errors.ExceptionList as e: log('Reddit error! {}'.format(e)) time.sleep(300) I build the alert text first and filled it with `str.format` and used the log function. ---------- The second to last task is to search in your emails for new messages and yield all alert texts: class ShortTimeOut(Exception): pass def search_for_alerts(mail): result, response = mail.uid('search', None, "(UNSEEN)") unread_msgs = response[0].split() if not unread_msgs: raise ShortTimeOut else: log('Something\'s wrong!') result, data = mail.uid('fetch', unread_msgs[-1], '(RFC822)') email_message = email.message_from_bytes(data[0][1]) for part in email_message.walk(): if part.get_content_type() == 'text/plain': yield part.get_payload() I yield the email contents (to be iterated over in the outer scope). I also added a custom exception to allow handling the short timeout in `main`. It seems to me like you did one request to many. After your first request you already have a list of all unseen emails, the last of which is the latest email. So there should be no need to do another request here. Lastly, I re-ordered the logic, so that if there are no new messages, no further requests are made. ---------- The last function is a main function, which calls all the other functions. It is executed in a `if __name__ == "__main__":` guard to allow importing your code from other scripts: def main(): while True: try: r = RUAlerts.login() mail = mail_login() try: for alert in search_for_alerts(mail): post_alert(alert, r) except ShortTimeOut: log('All clear on the RU front') time.sleep(30) except Exception as e: log('{} Retrying in 5 minutes'.format(e)) time.sleep(300) if __name__ == "__main__": main() ---------- **Final code:** import praw import imaplib import email import time import getpass import RUAlerts from datetime import datetime class ShortTimeOut(Exception): pass app_id = 'xxxxxxxxxxxx' app_secret = 'xxxxxxxxxxxx' app_uri = 'xxxxxxxxxxxx' app_scopes = 'account creddits edit flair history identity mysubreddits privatemessages read report save submit subscribe vote' app_ua = 'xxxxxxxxxxxx' app_account_code = 'xxxxxxxxxxxx' app_refresh = 'xxxxxxxxxxxx' def login(): r = praw.Reddit(app_ua) r.set_oauth_app_info(app_id, app_secret, app_uri) r.refresh_access_information(app_refresh) return r def log(text): print('\t{:%Y-%m-%d %H:%M:%S} - {}'.format(datetime.now(), text)) def mail_login(): mail = imaplib.IMAP4_SSL('imap.gmail.com') while True: try: emailpass = getpass.getpass( 'Please enter the password for xxxxxxx@xxxxx: ') mail.login('[email protected]', emailpass) break except imaplib.IMAP4.error: print('Incorrect password') mail.select("inbox") return mail def post_alert(alert, r): alert_text = """ {} ******** *^^I ^^am ^^a ^^bot. ^^For ^^any ^^questions, ^^comments, ^^or ^^concerns, ^^please ^^email [^^xxxxxxx@xxxxx](mailto://xxxxxxx@xxxxx)* """ while True: try: r.submit(subreddit='xxxxxxxxxxxx', title=alert, text=alert_text.format(alert)) print('\t{}'.format(alert), end=' ') break except praw.errors.ExceptionList as e: log('Reddit error! {}'.format(e)) time.sleep(300) def search_for_alerts(mail): result, response = mail.uid('search', None, "(UNSEEN)") unread_msgs = response[0].split() if not unread_msgs: raise ShortTimeOut else: log('Something\'s wrong!') result, data = mail.uid('fetch', unread_msgs[-1], '(RFC822)') email_message = email.message_from_bytes(data[0][1]) for part in email_message.walk(): if part.get_content_type() == 'text/plain': yield part.get_payload() def main(): while True: try: r = RUAlerts.login() mail = mail_login() try: for alert in search_for_alerts(mail): post_alert(alert, r) except ShortTimeOut: log('All clear on the RU front') time.sleep(30) except Exception as e: log("{}! Retrying in 5 minutes".format(e)) time.sleep(300) if __name__ == "__main__": main()