In early 2017 I wrote an article about using OAUTH / AUTHENTICATE with GMail. This is important because soon after I wrote this article / code (2013), GMail changed its policy to use OAUTH by default. Thus, the following / linked script would not work without reducing security in GMail. I also discuss how to reduce security ("Allow less secure apps") in the 2017 article.
I will probably never update this Python code for OAUTH in part because I outlined (in 2017) how to do this in PHP. If I were to write a script for OAUTH, it would be in PHP.
This script monitors a mailbox for new emails and email deletion. It uses the IMAP IDLE command to continuously monitor the box and detect activity within a few seconds or less. It writes activity to a file. You can then use "tail -f" or such from another program to do more processing.
I've tested it on GMail using a 14 minute interval of DONE (end idle), NOOP, and re-IDLE to keep the connection alive. In a few days of testing, it's stayed connected for 2 - 3 hours; I havnen't left it running for longer yet. It has error handling that should overcome lost connections.
I've seen IDLE called "email push" as opposed to polling. I'd call my script a listener or event handler.
The script also logs the IMAP mailbox UID and email-header Message-Id of both new messages and existing messages as they come up in the IMAP EXISTS stream of activity.
I'm testing in Windows 7, with-up-to-date updates as I'm writing this.
Do whatever you want with the code and this documentation, but I would like attribution even if this is just a distant inspiration. A link back to this page would be nice. Please feel free re-post any or all of this for redundancy.
Speaking of inspiration, I started in PHP with "2naive's" code. That code was very helpful.
You need to create an SSL Certificate, self-signed is fine. You don't need to put your real name or location, and those fields may not be required at all. As detailed in the Python doc, you can create a cert like this:
% openssl req -new -x509 -days 365 -nodes -out cert.pem -keyout cert.pem
You can get openssl for Windows from Cygwin and probably other places. I used version from-Cygwin "OpenSSL 1.0.1e 11 Feb 2013," but I'm pretty sure earlier versions will work. I haven't tested what happens when the cert expires; I don't know how GMail will react to that.
Should be very useful to understand what's going on.
The listener threads are to run multiple mailboxes. The idle threads are to "ping" the server with NOOP every 14 minutes.
There is some discussion on this on the web. I had some indication that 29 minutes would not work, but I'm not swearing that 14 minutes is the magic number.
Just as an FYI, one can probably use OAUTH with refresh tokens with GMail rather than one's email password.
I mentioned that I started in PHP. It seemed that neither threading nor forking was going to work in Windows. (I love the idea of Linux, I primarily used Linux for years, and I hope to return full-time one day, but as much as I hate to admit it, Linux can be painful to use as a workstation for anything beyond the basics.) Python appeared that it would work, and I'd been meaning to learn it. Eric Raymond recommended it years ago, and then XKCD did. (Note that I would take political advice from Raymond and not Munroe, but I'll take tech advice from Munroe.)
The openssl command I used will generate a 1024 bit SSL cert. I'm not certain of what will happen if you use a higher one, but in honor of Neal Stephenson's character Avi Halaby, I should try it with 4096 bits some time. (Cryptonomicon, fiction, 1999)
I put a VERSION_G (for global) variable in there and printed it to try to keep messups like last time from happening.
I created 3 ways to invoke:
With options 2 and 3, you run the risk of leaking your password in a shared environment. I think there are ways to make option 3 safe, but I'll leave that to others to ponder for now.
I had to provide an explicit pipe argument because getpass (in Windows 7) will hang, waiting for input despite the piped input.
Messed up the comments and took a few minutes to realize it. The previous version had a syntax error with the comments.
I took username / password out of the script itself and made them arguments. Note that people might see your arguments on shared hosts with the "ps" command or such. My understanding is that modern systems may tend to prevent such things, but you've been warned.
I did that after I posted my GMail password to the web for about 30 seconds. The web server access logs show that no one saw it, but I've changed my password anyhow.
This is a great argument for using OAUTH or something different.
The first public version (0.3.1) would exit after several exceptions. For 0.3.5, I observed that GMail terminates the connection more often than one would think, so I changed the exception handling to reset the exception count if there were no exceptions for a period of time. I haven't tested this in full.