CSAPawn
CSAPawn

Reputation: 77

Fetch a particular unseen email and print only those emails

To elaborate the question I have a code that searches for UNSEEN emails and stores the ID to a variable.

    status, messages = mail.select('Inbox')
    messages = int(messages[0])
    _, new_mails = mail.search(None, '(UNSEEN)')
    recent_mails = len(new_mails[0].split())
    print("Total Messages that is New:" , recent_mails)

    print(new_mails)

and it prints this:

Total Messages that is New: 2

[b'389 393']

What I want to do is the use these numbers to fetch it's contents like subject, who sent it and the body of the email. Is it possible to this implementation?

I have a previous code that fetches the first and beyond emails by indicating on how emails it will go to using the variable N code follows:

    N = 0

    for i in range(messages, messages-N, -1):
        # fetch the email message by ID
        res, msg = mail.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])
                # decode the email subject
                pre_subject, encoding = decode_header(msg["Subject"])[0]
                subject = pre_subject.upper()
                if isinstance(subject, bytes):
                    # if it's a bytes, decode to str
                    subject = subject.decode(encoding)
                # decode email sender
                From, encoding = decode_header(msg.get("From"))[0]
                if isinstance(From, bytes):
                    From = From.decode(encoding)
                print("Subject:", pre_subject)
                print("From:", From)
                # if the email message is multipart
                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)
                            plain = body
                        elif "attachment" in content_disposition:
                            # download attachment
                            filename = part.get_filename()
                            if filename:
                                folder_name = clean(subject)
                                if not os.path.isdir(folder_name):
                                    # make a folder for this email (named after the subject)
                                    os.mkdir(folder_name)
                                filepath = os.path.join(folder_name, filename)
                                # download attachment and save it
                                open(filepath, "wb").write(part.get_payload(decode=True))
                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)
                        plain = body
                print("="*100)

Upvotes: 0

Views: 295

Answers (1)

CSAPawn
CSAPawn

Reputation: 77

Finally for hours of experimenting I successfully implemented it.

Basically the ID I fetched on UNSEEN emails is converted to string from byte and then pass those number lists to the loop

    gmail_host = 'imap.gmail.com'
    mail = imaplib.IMAP4_SSL(gmail_host)
    mail.login(EMAIL_ADDRESS,EMAIL_PASSWORD)
    mail.list()
    status, messages = mail.select('Inbox')
    messages = int(messages[0])
    _, raw_mails = mail.search(None, '(UNSEEN)')
    recent_mails = len(raw_mails[0].split())
    splited = str(raw_mails[0], 'utf-8')
    new_emails = splited.split()
    print("Total Messages that is New:" , recent_mails)

    print(new_emails)

Output:

['378', '390']

And changed my for loop to this

for i in new_emails:

Upvotes: 1

Related Questions