Send to Kindle
I was looking for some Raspberry Pi project to do that not only used external hardware (even if that means only an LED for now), but also reached out into the net to deal with some kind of real time data. I ran into this t...
Send to Kindle
I was looking for some Raspberry Pi project to do that not only used external hardware (even if that means only an LED for now), but also reached out into the net to deal with some kind of real time data. I ran into this tutorial on adafruit about checking your gmail with a Pi and lighting up an LED based on whether or not you have new mail. This was along the lines of what I wanted to do, but had two drawbacks. One, I don’t use gmail anymore, and two, it uses a python library called feedparser, which is actually an RSS parser. It only works because apparently you can access your gmail as an RSS feed or something. I wanted to do the same thing, but with any email service that supports, say, IMAP4.
A bit of digging around and I found that Python has an imaplib library that can directly access any IMAP4 based 12mail account. This is included by default in the Python distro that comes with Raspbian. So no further setup there. It took a bit of fiddling around with the docs, both of the library itself and the IMAP4 specs, but I figured out the basic sequence.
The library docs are here: http://pymotw.com/2/imaplib/
And the IMAP4 spec is here: http://tools.ietf.org/html/rfc3501.html
First, you create an IMAP object with one of the following lines, depending whether you need SSL or not. My server does need it.
imap = imaplib.IMAP4(server, port)
imap = imaplib.IMAP4_SSL(server, port)
Then, you log in:
You then need to go into select mode to select IMAP folders and messages.
Then you can do a search. By default, you’ll be searching in your inbox, but there are methods to change folders as well. Search criteria are pretty powerful, but I just wanted to see how many unread messages I have. This does that:
type, data = imap.search(None, "UNSEEN")
The first parameter is the encoding. Using None will return messages with any encoding. Second param is the search criteria. See the IMAP4 spec linked above for a comprehensive list on what you can search for.
This will return a type, data tuple of strings. The type will be “OK” or “NO” depending on success of the call. Note, even if it returns no unread messages, you’ll still get “OK” here, with an empty string in the data.
The data will be an list of strings. Actually, it seems to generally be an list containing a single string. This string is a space delimited list of numbers. These numbers are ids of the messages returned by the search. It’ll be something like this: “1 2 3 4 5″.
You can split this into a list of individual ids like so:
messages = data.split()
And the length of this list tells you how many messages the search returned. Zero means no new mail. One or more and you have new mail! Fire up an LED!
Here’s the full program I wrote:
import imaplib, time
import RPi.GPIO as GPIO
GREEN_PIN = 25
RED_PIN = 24
def __init__(self, server, port):
self.m = imaplib.IMAP4_SSL(server, port)
self.do_error("Unable to contact server")
def do_error(self, error):
# maybe flash another error LED
def log_in(self, user, password):
self.do_error("Unable to log in")
type, data = 0, 0
type, data = self.m.search(None, "UNSEEN")
self.do_error("Unable to check messages")
if type == "NO":
self.do_error("Problem checking messages")
def start_checking(self, interval):
def report(self, data):
message_count = len(data.split())
if message_count > 0:
print("You've got %i new messages" %