Search code examples
pythonemailimaplib

Python imaplib only check message if its unread


I am trying to set imaplib to only only work, if there is a new email in the inbox. I tried to do this with a code I found online, and added a while loop to it, and it works perfectly, but it always prints the message even if its he same email. Here is what i did:

import imaplib
import email
mail = "[email protected]"
password = "password"
imap = imaplib.IMAP4_SSL("imap.gmail.com")
imap.login(mail,password)
N = 1

while True:

            status, messages = imap.select("INBOX")
            messages = int(messages[0])

            for i in range(messages, messages-N, -1):
                res, msg = imap.fetch(str(i), "(RFC822)")
                for response in msg:
                    if isinstance(response, tuple):
                        # parse a bytes email into a message object
                        msg = email.message_from_bytes(response[1])
                        if msg.is_multipart():
                            # iterate over email parts
                            for part in msg.walk():
                                # extract content type of email
                                content_type = part.get_content_type()
                                content_disposition = str(part.get("Content-Disposition"))
                                try:
                                    # get the email body
                                    body = part.get_payload(decode=True).decode()
                                except:
                                    pass
                                if content_type == "text/plain" and "attachment" not in content_disposition:
                                    # print text/plain emails and skip attachments
                                    print(body)
                        else:
                            # extract content type of email
                            content_type = msg.get_content_type()
                            # get the email body
                            body = msg.get_payload(decode=True).decode()

                            if content_type == "text/plain":
                                # print only text email parts
                                print(body)

This does the job, and prints the message of the newest email, and if i send a new email it will read that, change the body to the new message and print it. But my problem is that it will keep printing the the same message, until a new one arrives, and than it prints that again and again until another one arrives. Like this:

this is a message # keeps printing it until new email arrives
this is a message
this is a message
this is a message
# new email arrives
this is the message of the new email
this is the message of the new email
this is the message of the new email

How can I make it so, that it only checks for new/unread emails, or it only activates when there is a new email in the inbox? Maybe there is something that can put it into an idle mode?


Solution

  • I found a solution. It doesnt really stop it from operating, but it will only print it once. Its a really easy fix, with the use of lists. I added a list and a messagid variable, to wich we add 1 everytime the loop resets:

    messageid = 0
    messagelist = ["first"]
    while True:
        messageid += 1
    

    And instead of print(body), what I did was:

    messagelist.append(body)
    if messagelist[messageid] != messagelist[messageid-1]:
        print(body)
    

    This will only print the body if it isnt the same as the one before.