Octopus
Octopus

Reputation: 159

check if email inbox is empty (imaplib, python3)

I'm writing a script that reads emails and then answers something based on the header. It checks the inbox in an interval and then responds to any emails in the inbox. In the end it moves all read emails to the deleted folder:

import time
import sys
import imaplib
import smtplib
import getpass
import email
import email.header
import datetime

EMAIL_ACCOUNT = "YOUR_EMAIL_ACCOUNT"
PW = "YOUR_PASSWORD"

EMAIL_FOLDER = "INBOX"

def process_mailbox(M):
    #try to log in to the mail server with your credentials
    try:
        rv, data = M.login(EMAIL_ACCOUNT, PW) 
        print(rv, data)
    except imaplib.IMAP4.error: #except an error and exit
        print ("LOGIN FAILED!")
        sys.exit(1)

    #set the mail server for reading mails          
    rv, data = M.select(EMAIL_FOLDER)
    print(rv, data)
    rv, data = M.search(None, "ALL") 

    # !!-----------------------------------------------------
    #here rv always return "OK" therefore the next if clause
    #also is always false although it should be True

    if rv != 'OK': #
        print("No messages found, when i tried at", datetime.datetime.now())
        return   

    for num in data[0].split():
        rv, data = Mailbox.fetch(num, '(RFC822)') #returns tuple fetch(message_set, message parts)    
        if rv != 'OK': #if rv (assigned above) is OK print an error message and return
            print("ERROR getting message", num)
            return

        msg = email.message_from_bytes(data[0][1])
        #decode the header and make a readable header
        hdr = email.header.make_header(email.header.decode_header(msg['Subject']))
        subject = str(hdr) #convert the header to a string

    for num in data[0].split(): #for all the mail in the directory
        box.store(num, '+FLAGS', '\\Deleted') #flag them as deleted

    box.expunge()  #and delete them all

    Mailbox.close() 
    Mailbox.logout()


while True:
    print("Processing mailbox...\n")
    Mailbox = imaplib.IMAP4_SSL('imap.gmail.com')
    process_mailbox(Mailbox)
    time.sleep(10)

I've found the code if rv != "OK": somewhere but it seems not to be working correctly (anymore?) since rv is always "OK" no matter whether there are emails in the inbox. I've tried looking into the IMAP documentation but i've not found any arguments for search that could have assessed the state.

What is the proper way to check whether (in this case) the inbox is empty?

Thanks you for your help in advance!

Upvotes: 0

Views: 2096

Answers (2)

Octopus
Octopus

Reputation: 159

I have found the correct answer to the problem: rv, data = Mailbox.search() returns a simple string in the data variable. I just didnt print out the correct which gets overwriten everytime.

if data == [b'']: 
    print("The mailbox is empty")
    return

As easy as it gets. I'll accept arnt's answer since i got help from there.

Upvotes: 0

arnt
arnt

Reputation: 9685

If there are no messages, then an IMAP search for ALL returns OK and 0 messages. Put differently, the OK means that the server was able to interpret and execute it as you wished. The alternatives are NO (e.g. a permission problem) or BAD (e.g. a syntax error). Status OK and zero results means empty, another status means that you don't know.

BTW, I suggest that you call expunge only once, at the end, instead of after every store. It'll do the same and run faster.

Upvotes: 1

Related Questions