Ittefaq Technologies
Ittefaq Technologies

Reputation: 29

How to sync smtp mailbox to local inbox

I am creating an email campaign system with several connected accounts. I periodically fetch emails from SMTP through IMAP and store them locally in my inbox. How can I sync inbox with the SMTP server, like webmail I am using? Or how can I determine where to start fetching because I am not finding any unique identifier?

Here is my code

def fetch_emails(connected_account, count=10):
    try:
        
        imap_server = connected_account.server
        username = connected_account.server
        password = connected_account.password
        # Connect to the IMAP server
        mail = imaplib.IMAP4_SSL(imap_server)
        mail.login(username, password)
        
        # Select the mailbox (inbox)
        mail.select('inbox')

        # Search for the most recent emails in the inbox
        status, data = mail.search(None, 'ALL')
        if status != 'OK':
            print("No messages found!")
            return []

        emails = []
        # Decode the byte string data to a regular string and split it into individual IDs
        email_ids = data[0].decode().split()
        
        # Limit the number of emails to fetch to 'count' (default is 10)
        email_ids = email_ids[-count:] if len(email_ids) > count else email_ids

        # Iterate through each email id
        for num in email_ids:
            print(num)
            # Fetch the email data
            status, msg_data = mail.fetch(num, '(RFC822)')
            
            for response_part in msg_data:
                if isinstance(response_part, tuple):
                    # Parse a bytes email into a message object
                    msg = email.message_from_bytes(response_part[1])

                    # Decode the email subject
                    subject, encoding = decode_header(msg["Subject"])[0]
                    if isinstance(subject, bytes):
                        subject = subject.decode(encoding if encoding else 'utf-8')

                    # Decode the email sender
                    sender, encoding = decode_header(msg.get("From"))[0]
                    if isinstance(sender, bytes):
                        sender = sender.decode(encoding if encoding else 'utf-8')

                    # Initialize attachment list
                    attachments = []

                    # Get the email body and attachments
                    if msg.is_multipart():
                        for part in msg.walk():
                            content_type = part.get_content_type()
                            content_disposition = str(part.get("Content-Disposition"))

                            # Handle attachments
                            if "attachment" in content_disposition:
                                filename = part.get_filename()
                                if filename:
                                    if isinstance(filename, bytes):
                                        filename = filename.decode(encoding if encoding else 'utf-8')
                                    attachments.append(filename)
                                    
                                    # Save the attachment
                                    filepath = os.path.join("attachments", filename)
                                    with open(filepath, "wb") as f:
                                        f.write(part.get_payload(decode=True))
                            elif content_type == "text/plain" and "attachment" not in content_disposition:
                                # Get the email body
                                body = part.get_payload(decode=True).decode()
                                email_content = {
                                    "subject": subject,
                                    "from": sender,
                                    "body": body,
                                    "attachments": attachments
                                }
                                emails.append(email_content)
                                break
                    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
                            email_content = {
                                "subject": subject,
                                "from": sender,
                                "body": body,
                                "attachments": attachments
                            }
                            emails.append(email_content)

        # Logout from the server
        mail.logout()

        return emails

    except Exception as e:
        print("Error:", str(e))
        return []

Upvotes: 0

Views: 33

Answers (0)

Related Questions