JCoder96
JCoder96

Reputation: 188

Python IMAP TypeError: 'Nonetype' Object Is Not Subscriptable

I am using imap to check for unread emails that match a specific subject. When I receive an email from my test email, it goes just fine, but when it comes from an automatic system that I'm needing it to check the emails from, I get an error stating that 'Nonetype' object is not subscriptable. The following is my code:

import imaplib, time, email, mailbox, datetime
server = "imap.gmail.com"
port = 993
user = "Redacted"
password = "Redacted"

def main():
    while True:            
        conn = imaplib.IMAP4_SSL(server, port)
        conn.login(user, password)
        conn.list()
        conn.select('inbox', readonly=True)
        result, data = conn.search(None, '(UNSEEN SUBJECT "Alert: Storage Almost At Max Capacity")')
        i = len(data[0].split())

        for x in range (i):
            latest_email_uid = data[0].split()[x]
            result, email_data = conn.uid('fetch', latest_email_uid, '(RFC822)')
            raw_email = email_data[0][1] #This is where it throws the error
            raw_email_string = raw_email.decode('utf-8')
            email_message = email.message_from_string(raw_email_string)
            date_tuple = email.utils.parsedate_tz(email_message['Date'])
            local_date = datetime.datetime.fromtimestamp(email.utils.mktime_tz(date_tuple))
            local_message_date = "%s" %(str(local_date.strftime("%a, %d %b %Y %H:%M:%S")))
            for part in email_message.walk():
                if part.get_content_type() == "text/plain":
                    body = part.get_payload(decode=True)
                    body = body.decode('utf-8')
                    body = body.split()
                    #Do some stuff
        conn.close()

if __name__ == "__main__":
    main()

And the following is the traceback:

Traceback (most recent call last):
    File "TestEmail.py", line 200, in <module>
        main()
    File "TestEmail.py", line 168, in main
        raw_email = email_data[0][1]
TypeError: 'NoneType' object is not subscriptable.

I don't understand why this would work in an email sent from a person's email, yet not work when my system emails me an alert. Is there any obvious fix to this?

EDIT: I've tried printing the result and email variables. The following was their output:

Result: OK
Email: [None]

Whereas if I test the script against an email with the same subject, but sent from my test email, result is still "OK", but an email is contained.

EDIT#2: I've noticed that the format of the emails are a little different. The one that is being received fine is both text/plain and text/html, whereas the one that isn't being accepted is text/plain with Content-Transfer-Encoding: 7-bit. How might I remedy this? If I forward the email through a filter and check the email receiving from the filter, my code works just fine. However, I would like to not have to use multiple emails for this.

Upvotes: 1

Views: 1185

Answers (1)

Max
Max

Reputation: 10985

You are searching for message sequence numbers, and fetching by uid. If you are going to use conn.uid('fetch'), you must also use conn.uid('search'), otherwise you are searching for apples and fetching oranges.

Thus, since not all MSNs are UIDs, you are occasionally fetching non-existent messages, which is not an error, but it just won't return you anything.

Upvotes: 1

Related Questions