How to Use Python’s imaplib to check for new emails(continuously)

Juanrosario
4 min readMar 4, 2023

--

The code imports several libraries, including time, imaplib, email, base64, os, and re. These libraries are used for time management, email retrieval, and attachment processing. The email retrieval process is made possible by connecting to the Gmail IMAP server using the imaplib library.

import time
from itertools import chain
import email
import imaplib
import base64
import os
import re

After importing the required libraries, the code initializes variables for the IMAP host, port, username, and password. In this case, the IMAP server is the Gmail server, and the email account used is a placeholder your-email@gmail.com. The uid_maxvariable is set to zero, which means that only new emails will be processed.

imap_ssl_host = 'imap.gmail.com'
imap_ssl_port = 993
username = 'your-email@gmail.com'
password = 'your-password'

Next, the search_string function is defined. This function takes two arguments, uid_max and criteria. The uid_maxargument is used to get new emails only, while the criteria argument is used to restrict the search based on the email sender, subject, or body.

criteria = {}
uid_max = 0

def search_string(uid_max, criteria):
c = list(map(lambda t: (t[0], '"'+str(t[1])+'"'), criteria.items())) + [('UID', '%d:*' % (uid_max+1))]
return '(%s)' % ' '.join(chain(*c))

The code then logs in to the IMAP server using the IMAP4_SSL method and selects the inbox folder. The uid method is used to search for new emails that match the search criteria using the search_string function. The uids variable is assigned a list of unique identifiers (UIDs) that correspond to the search criteria.

The uid_max variable is set to the maximum UID value from the list of UIDs. The uid_maxvariable is then used to fetch the email's RFC822 data, which includes the email's metadata and body.

mail = imaplib.IMAP4_SSL(imap_ssl_host)
mail.login(username, password)
#select the folder
mail.select('inbox')

result, data = mail.uid('SEARCH', None, search_string(uid_max, criteria))
uids = [int(s) for s in data[0].split()]
if uids:
uid_max = max(uids)
mail.logout()

The while loop is then used to continually check for new emails every second. The IMAP4_SSL method is used to log in to the IMAP server, select the inbox folder, and search for new emails that meet the search criteria. The uids variable is assigned a list of UIDs that correspond to the search criteria.

The for loop is then used to process each email in the uids list. If the UID value is greater than the uid_max value, the fetch method is used to get the email's RFC822 data. The message_from_bytes method is used to parse the email data, and any attachment related to the email is processed.

The uid_max variable is then updated to the current UID value, ensuring that only new emails are processed in the next iteration of the while loop.

In conclusion, the Python code presented in this article demonstrates how to use Python’s IMAP library to retrieve emails from Gmail. The code allows you to search for emails based on different criteria and process any attachment related to the emails. With this code, you can automate the process of retrieving emails and save time on manual email retrieval.

while 1:
mail = imaplib.IMAP4_SSL(imap_ssl_host)
mail.login(username, password)
mail.select('inbox')
result, data = mail.uid('search', None, search_string(uid_max, criteria))
uids = [int(s) for s in data[0].split()]

for uid in uids:
# Have to check again because Gmail sometimes does not obey UID criterion.
if uid > uid_max:
result, data = mail.uid('fetch', str(uid), '(RFC822)')
for response_part in data:
if isinstance(response_part, tuple):
#message_from_string can also be use here
print(email.message_from_bytes(response_part[1])) #processing the email here for whatever
uid_max = uid
mail.logout()
time.sleep(1)

Complete code:import time
from itertools import chain
import email
import imaplib
import base64
import os
import re

imap_ssl_host = 'imap.gmail.com'
imap_ssl_port = 993
username = 'juanrosario38@gmail.com'
password = “”

# if need to restrict mail search.
criteria = {}
uid_max = 0

def search_string(uid_max, criteria):
c = list(map(lambda t: (t[0], '"’+str(t[1])+’"’), criteria.items())) + [(’UID’, '%d:*' % (uid_max+1))]
return '(%s)' % ' '.join(chain(*c))
# Produce search string in IMAP format:
# e.g. (FROM "me@gmail.com" SUBJECT "abcde" BODY "123456789" UID 9999:*)
#Get any attachemt related to the new mail

#Getting the uid_max, only new email are process

#login to the imap
mail = imaplib.IMAP4_SSL(imap_ssl_host)
mail.login(username, password)
#select the folder
mail.select(’inbox’)

result, data = mail.uid(’SEARCH’, None, search_string(uid_max, criteria))
uids = [int(s) for s in data[0].split()]
if uids:
uid_max = max(uids)
# Initialize `uid_max`. Any UID less than or equal to `uid_max` will be ignored subsequently.
#Logout before running the while loop
print(uid_max)
mail.logout()
while 1:
mail = imaplib.IMAP4_SSL(imap_ssl_host)
mail.login(username, password)
mail.select(’inbox’)
result, data = mail.uid(’search’, None, search_string(uid_max, criteria))
uids = [int(s) for s in data[0].split()]

for uid in uids:
# Have to check again because Gmail sometimes does not obey UID criterion.
if uid > uid_max:
result, data = mail.uid(’fetch’, str(uid), '(RFC822)’)
for response_part in data:
if isinstance(response_part, tuple):
#message_from_string can also be use here
print(email.message_from_bytes(response_part[1])) #processing the email here for whatever
uid_max = uid
mail.logout()
time.sleep(1)

--

--