September 16, 2022

Testing IMAP IDLE/NOTIFY with python

by orzel
Categories: Admin, Software
Tags: ,
Comments: Leave a Comment

I have to troubleshoot a buggy relationship between a mail client (thunderbird) and an IMAP server (dovecot), regarding notification. That’s when the server informs the client about new mails, as opposed to the client polling the server to get this information.

There’s this stackoverflow thread with some very useful exemple code. Unfortunately, it’s old, and python 2 only.

For the record, here’s the version I’ve used, updated to p3k, and with some slight modifications: single file, reporting exception in the main loop instead of just ignoring them with the ‘finally’ close. It’s not as clean and efficient as I would like, but it works and is not THAT dirty.

File imapidletest.py

import imaplib
import configparser
from os.path import abspath

def open_connection(verbose=False):
    # Read the config file
    config = configparser.ConfigParser()
    config.read([abspath('settings.ini')])

    # Connect to the server
    hostname = config.get('server', 'hostname')
    if verbose: print('Connecting to', hostname)
    connection = imaplib.IMAP4_SSL(hostname)

    # Login to our account
    username = config.get('account', 'username')
    password = config.get('account', 'password')
    if verbose: print('Logging in as', username)
    connection.login(username, password)
    return connection

imaplib.Debug = 4
c = open_connection()
try:
    c.select('INBOX', readonly=True)
    c.send(b"%s IDLE\r\n"%(c._new_tag()))
    print(">>> waiting for new mail...")
    while True:
      line = c.readline().strip();
      if line.startswith(b'* BYE ') or (len(line) == 0):
        print(">>> leaving...")
        break
      if line.endswith(b'EXISTS'):
        print(">>> NEW MAIL ARRIVED!")
except Exception as e:
    print("Exception:")
    print(e)
finally:
    try:
        print(">>> closing...")
        c.close()
    except:
        pass
    c.logout()

You need a file settings.ini like this one:

[server]
hostname: imap.xxx.com

[account]
username: mylogin
password: my_clear_password

Leave a Reply

Your email address will not be published. Required fields are marked *