Using XOAuth was not what I planned to do in the first place, I was trying to using OAuth from an installed application because I read this FAQ entry. I was able to get the access token but whatever the request I tried, I kept getting 401 error. However, I can using Google OAuth Playground to get the Atom feed. So I am guessing that application uses oauth_callback=oob can’t get you authorized when you try to request Gmail Atom feed even you have the access token. But, I am not sure. You can also see there is a page about Atom feed API, it doesn’t mention about OAuth, but the email and password. It’s clear that’s about HTTP Basic Authentication, which we have been using for a long time.

Anyway, today I was still trying to poke at Gmail, thinking I might get lucky. I did, in different way, I found Gmail IMAP and SMTP using OAuth. Using IMAP to get inbox information isn’t that bad, it’s just a bit of slower. In this page, it’s clear that Gmail doesn’t say it allows you use OAuth authentication to access via HTTP, but you can access via IMAP and SMTP using OAuth, XOAuth to be more precise.

A walkthrough for Python was also posted, the procedure of requesting the access token is almost the same as I did with OAuth. After you get the access token, you will need it to generate something called XOAuth Authentication String, it is used in IMAP authentication.

The library xoauth.py()1 is also a standalone program, but you can only test if the credential is valid or not as much as it can do. I wrote gmail-xoauth.py(), it shows you the unread count and a list of unread messages. You will need xoauth.py to run gmail-xoauth.py.

It stores your email address and access token to config.py for later use, here is an example output:

http://farm5.static.flickr.com/4079/4909178140_7b6fd0e65a_z.jpg

Don’t worry, you can run it with Python 2.6, only Python will tell you that xoauth.py uses deprecated library.

Once we have access toke, it calls xoauth.GenerateXOauthString() to get the authentication string. You probably have seen I temporarily mute the output when invoking that function. It prints out some debug messages which we don’t want users to read.

Then, it logs in via IMAP using XOAuth authentication. It selects your INBOX and make sure we do in read-only method so the script won’t cause any message to be marked as seen (as read). search() returns the unseen messages’ IDs. It count the message and show the user, then it formats a message set, a list of ids, comma-separated values, and fetch() those messages for the RFC822 header. It use email package to parse and decode headers, then print out the list.

The code isn’t tested fully, you may run into something.

[1]http://google-mail-xoauth-tools.googlecode.com/svn/trunk/python/xoauth.py is gone.