Alibaba Mail IMAP scenario example: Get email information (SELECT, SEARCH, and FETCH)

更新时间:
复制 MD 格式

Basic flow

image

Key actions

  • SELECT

Selects a mailbox to be the target of the current operation.

  • SEARCH

Searches for emails that meet specific conditions.

  • FETCH

Retrieves the details of a specific email.

Important

Important: The following code was tested in Python 3.11.9. Test the code thoroughly before you use it in a production environment.

Python code example

Scenario: Log in to a mailbox, select the inbox, search for unread emails, and retrieve the original EML content of the emails.

# -*- coding: utf-8 -*-
import imaplib
from imapclient import imap_utf7

imap_server = 'imap.qiye.aliyun.com'
username = 'test@example.com'
password = '********'
imap_port = 993

# Connect to the IMAP server
mail = imaplib.IMAP4_SSL(imap_server, imap_port)
mail.login(username, password)

# Select a mailbox (for example, "INBOX")
folder_name = imap_utf7.encode('INBOX')  # UTF-7 encoding for Chinese characters
mail.select(folder_name)

# Search for unread emails
status, data = mail.search(None, 'UNSEEN')
if status == 'OK':
    mail_ids = data[0].split()
    for mail_id in mail_ids:
        # Get the full content of the email
        status, msg_data = mail.fetch(mail_id, '(RFC822)')
        if status == 'OK':
            print(f"Email ID: {mail_id.decode()}")
            print("Email body:")
            print(msg_data[0][1].decode())

# Close the connection
mail.logout()

Parameter examples

Notes for SELECT

Chinese folder names must be UTF-7 encoded.

import imaplib
from imapclient import imap_utf7

imap_server = 'imap.qiye.aliyun.com'
username = 'test@example.com'
password = '******'
port = 993

mail = imaplib.IMAP4_SSL(imap_server, port)
# Log on
mail.login(username, password)
# Select a mailbox (for example, "Inbox")
folder_name = imap_utf7.encode('Inbox')  # Use UTF-7 to encode non-ASCII folder names (e.g., Chinese).
mail.select(folder_name)
print('Mailbox selected')

FAQ

If a folder encoding fault occurs, use the list command to view the folder name. For Chinese encoding, use imap_utf7.

imaplib.IMAP4.error: SELECT command error: BAD [b'invalid command or parameters']
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)

Supported parameters for SEARCH

import imaplib
from imapclient import imap_utf7

imap_server = 'imap.qiye.aliyun.com'
username = 'test@example.com'
password = '******'
port = 993

mail = imaplib.IMAP4_SSL(imap_server, port)
# Log on
mail.login(username, password)
# Select a mailbox (for example, "INBOX")
folder_name = imap_utf7.encode('INBOX')  # UTF-7 encoding for Chinese characters
mail.select(folder_name)

# search examples
status, data = mail.search(None, 'SEEN')  # Read
# status, data = mail.search(None, 'UNSEEN')  # Unread
# status, data = mail.search(None, 'ALL')  # All
# status, data = mail.search(None, '(SEEN)')  # Alternative syntax
# status, data = mail.search(None, '(SEEN UNSEEN)')  # Supports multiple conditions
# status, data = mail.search(None, 'SEEN', ' UNSEEN')  # Supports multiple conditions, separated by commas
# status, data = mail.search(None, '1')  # UID
# status, data = mail.search(None, '(1 2)')  # UIDs # Supports multiple UIDs
# status, data = mail.search(None, 'ON 10-Jan-2024')  # Search for emails from a specific day
# status, data = mail.search(None, 'SINCE 10-Jan-2024')  # Search for emails on or after a specific day
# status, data = mail.search(None, "(SINCE 05-Dec-2023 BEFORE 12-Jan-2024)")  # SINCE is the start date, BEFORE is the end date
#
# status, data = mail.search(None, 'BEFORE', '12-Jan-2024', 'SEEN')  # Search for emails before a specific date, excluding that date
# status, data = mail.search(None, 'BEFORE', '12-Jan-2024', 'SEEN', 'ON 05-Dec-2023')  # Supports multiple conditions. ON searches for emails from a specific day
# status, data = mail.search(None, 'BEFORE 12-Jan-2024', 'SEEN', 'ON 05-Dec-2023')  # Alternative syntax
# status, data = mail.search(None, 'BEFORE 12-Jan-2023 SEEN ON 05-Dec-2022')
# status, data = mail.search(None, "SENTSINCE 26-Mar-2024")  # Emails sent since a specific date
print(status, data)  # Returns UID information

Run result

image

Unsupported parameter examples for SEARCH

# mail.search(None, '(SUBJECT "Subject")')
# mail.search(None, 'SUBJECT "Test"'.encode('utf-8'))
# mail.search(None, 'OR FROM "a***@example.net"', 'SUBJECT "Test"'.encode('utf-8'))
# mail.search(None, '(FROM "Nickname")')
# mail.search(None, 'FROM', '"Nickname"')

# mail.search('GB2312', 'FROM "**example**.com"')
# mail.search(None, '(FROM "Doug" SUBJECT "Example message 2")')
# mail.search(None, "FROM", '"Nickname"')
# mail.search([u'SINCE', date(2024, 1, 20)])

Supported parameters for FETCH

import imaplib
from imapclient import imap_utf7

imap_server = 'imap.qiye.aliyun.com'
username = 'test@example.com'
password = '******'
port = 993

# Connect to the IMAP server
mail = imaplib.IMAP4_SSL(imap_server, port)
mail.login(username, password)

# Select a mailbox (for example, "INBOX")
folder_name = imap_utf7.encode('INBOX')  # UTF-7 encoding for Chinese characters
mail.select(folder_name)

# Search for unread emails
status, data = mail.search(None, 'UNSEEN')
if status == 'OK':
    mail_ids = data[0].split()
    for mail_id in mail_ids:
        # Get the full content of the email
        f_status, msg_data = mail.fetch(mail_id, '(RFC822)')
        # f_status, msg_data = mail.fetch(num, 'UID')  # v_type1= OK data1= [b'1 (UID 12)']
        # f_status, msg_data = mail.fetch(num, 'BODY[]')  # Equivalent to (RFC822)
        # f_status, msg_data = mail.fetch(num, '(UID BODY[HEADER])')  # Returns the complete file header information.
        # f_status, msg_data = mail.fetch(num, '(UID BODY[HEADER.FIELDS (Subject)])')  # You can specify specific fields to return in parentheses, such as Subject.
        # f_status, msg_data = mail.fetch(num, '(UID BODY[TEXT])')  # Email body. The returned data is a tuple of message part data.
        # f_status, msg_data = mail.fetch(num, 'FLAGS')[1]  # [b'3 (UID 16 FLAGS (\\Seen))'] # To get the UID, you need to process the returned data.

        if f_status == 'OK':
            print(f"Email ID: {mail_id.decode()}")
            print("Email body:")
            print(msg_data[0][1].decode())

# Close the connection
mail.logout()

Run result

image

Unsupported parameters for FETCH

# status, data = mail.fetch(num, '(UID BODY[HEADER.FIELDS.NOT (Subject)])')
# status, data = mail.fetch('2:3', '(RFC822)')  # Range

FAQ

The following faults indicate that the parameters for the SEARCH or FETCH action are incorrect or unsupported. Use the supported command parameters as shown in the examples.

imaplib.error: SEARCH command error: BAD [b'invalid command or parameters']
imaplib.error: FETCH command error: BAD [b'invalid command or parameters']