Using APIs: GMail as an Example
Welcome
One of our goals in this class is to gain a good understanding of how software is constructed. A key component of good software design is to expose functionality in the form of libraries, and then provide clean application programming interfaces (APIs) to those libraries.
The GMail API is a great way to get comfortable with APIs. It's fun, because you'll know if you're doing things correctly or not. But more importantly, there's a lot to learn here about how good APIs are designed. Google really wants to make it easy for developers, and so there are websites where you can issue requests and get JSON back. Once you know what you're going to get, then you can go ahead and write the Java code to actually get it.
Step 1 : Getting Permission to Access GMail from Java
The first step is to get permission to use the GMail API. This is "step 1" of the GMail Java Quickstart Guide. When you're done, you should have a "client_secret.json" file that stores your API keys.
Step 2 : Some Quick Java Set-Up
As was the case last week, I strongly recommend that you use an IDE for this, since an IDE will give you autocompletion. At the same time, it's nice to see the guts of what's really going on. Let's do it both ways.
If you follow the quickstart guide above, it's going to tell you to set up an IDE (I used eclipse), download the GMail Java Client Library, and then import all of the jars into your project. Sure, you could do that, but you don't need all of those jars (and you do need one jar they don't redistribute: the javax.mail jar... you can get it from Oracle, or see below).
If it's later than March 2015, you should not use the links I'm about to provide. They are to the copies of the library code that I downloaded in February 2015. They're going to be obsolete sooner or later (or maybe they have a to-be-patched security vulnerability). However, for convenience, here they are:
- google-api-client-1.19.1.jar
- google-api-services-gmail-v1-rev22-1.19.1.jar
- google-http-client-1.19.0.jar
- google-http-client-jackson2-1.19.0.jar
- google-oauth-client-1.19.0.jar
- jackson-core-2.1.3.jar
- javax.mail.jar
If you're using an IDE, you just need to put these on your path. If you want to build and run from the command line, then I recommend the following project structure for this tutorial:
- ./lib/ — where to put the jars
- ./src/ — where to put your java files
- ./ — where to put your JSON file
Lastly, here's an ant buildfile for our project.
Be sure to put your source code in a folder called "src" if you want this to work.
Step 3 : Bouncing Between JavaScript and Java
Let's start exploring the API. We'll start by listing thread ids and message ids. This isn't necessarily the most useful thing to do, but it's a nice way to start. Go to this page and you'll see that you can (1) turn on OAuth 2.0, and then (2) use the form to list the thread IDs. When in doubt, use "me" as the userId.
If all goes well, you should see something like this:
This response is being generated by a GET to a REST interface. If we could do the same request via Java, we'd be able to get the same data (in a more strongly typed form). Let's try it.
First, we're going to need some code that connects to the GMail services. This is going to be done via OAuth 2.0, and fortunately, we can do it via Java. The experience is a bit interesting... I'll let you see what I mean. Start with code like this:
In this example, we only need read-only access. To send messages, you'll need at least "compose" permission. For more information about permissions, see this page
When you run this code, you should be able to get a list of threads, similar to the way the web request worked.
Step 4 : Explore
It's time to explore. You should start by trying to get messages. Start with the API explorer, then try to switch to Java code. You'll see that the web page has an (incomplete) Java snippet to help you along the way. But things don't always work nicely. Some messages don't have "parts", for example. In my case, I had to get my messages with this command:
I'm not sure why I needed to use a wildcard query. Maybe if I went back now, I'd realize that the more natural way to do this works, and I was just doing something dumb.
Anyhow, I'm going to put the rest of this tutorial online later in the week, because I want you to figure out this API on your own. You should be able to do (at least) the following:
- Fetch messages and display their subject. (hint: it's in the headers of the payload)
- Display message bodies for messages that have bodies (You'll need to use Base64.decodeBase64 from the apache.commons package)
- Save attachments from messages. You'll need to use getParts() and then figure out which parts have file names associated with them.
- Use javax.mail to send messages through GMail. The documentation for how do to this doesn't give you everything in one listing, and it doesn't talk about exception handling. Your code should handle exceptions well. You'll also need to change your app's permissions at this point.
- Attach files to the emails that you send.
Step 5 : Next Steps
Like I said earlier, I'll provide code for the above tasks, but not until later in the week. Your goal is to explore and try to figure this out on your own. When you're in the "real world", you'll be expected to do this alone.
The first "next step" this week is to use GMail labels in a clever way. My suggestion is to get all messages with some special token in the subject line, and then to label them after they are processed, so that they don't get processed again.
The next "next step" is to go a step farther, and actually delete messages after processing them. This isn't hard, but it takes some confidence to trust your code enough to let it delete something that's live in your inbox.
The last "next step" is to create a long-running program that authenticates once, and then keeps on sending queries, maybe once per minute, to see what new stuff has arrived and to act on it. You might even want to look at the Google Developer OAuth2 Page to learn a bit about token expiration and refresh.