Getting started with Context.IO

In this getting started guide, we will cover how to create a sample application on Context.IO's Lite API.

While you can interact with our API using standard HTTP verbs and JSON, we recommend following along with our code samples in Ruby and PHP and using their respective libraries to interface with Context.IO.

Along the way will discuss concepts and sample code related to signing requests, creating a user, and adding an email_account via connect_tokens.

We will also discuss how to fetch folders, list messages in a folder, view a message, and set the "read" flag on a message.

Disclaimer

This document and the accompanying sample applications aren't meant to be production code.

Ruby example CLI app is available here.
PHP example CLI app is available here.

What is Context.IO?

Context.IO is an api that is used to interface with your users' email account(s). There are several versions of the API. We will focus on our latest and greatest version: Lite. There is detailed documentation on our main website located at http://context.io/docs/lite. Context.IO abstracts away IMAP, letting you focus on building your application on top of email data. For testing we recommend you create a throwaway email account.

How do I use Context.IO Lite?

First, create an account at Context.IO. This will create your developer API key and secret, which you'll use to make all API calls.

Next, ensure you can sign-in to our developer console.

The developer console is an easy way to view user accounts associated with your API key, issue API calls from our explorer, and look at recent statistics and logs.

If you have any problems following the code examples you can use the explorer to issue most of the calls and inspect the request/response to help troubleshoot. You can always email support@context.io for help.

Now let's get down to writing code!

Signing Requests

Your OAuth Consumer Key and Secret can be found at https://console.context.io/#settings.

Context.IO requires registered developers to present their credentials to the API on every request using OAuth 1. This process is called "signing" your request. In a nutshell, we require you to take your OAuth consumer secret (aka password), the current time, a nonce (number used once) and create a hash (SHA-1) to include with your request. When we receive your request, we do the same thing on our end using our own OAuth consumer and secret. If your hash matches up with our generated hash, then we know your application made the request.

Luckily, the plumbing for signing each API request is taken care of automatically if you use one of our client libraries. When you instantiate the library you pass your OAuth Consumer Key and Secret to the object and then our library then uses them on each subsequent request into our API. You can read more about signing requests here if you're thinking about manually signing your requests.

Here's how to use our library to sign your API requests:

PHP

// define your API key and secret - find this https://console.context.io/#settings
define('CONSUMER_KEY', 'YOUR API CONSUMER KEY');
define('CONSUMER_SECRET', 'YOUR API CONSUMER SECRET');

// instantiate the contextio object
$contextio = new ContextIO(CONSUMER_KEY, CONSUMER_SECRET);

RUBY

cio = ContextIO.new(api_key, api_password)

Adding your first user

With Context.IO you have two ways to add a user to your account, API calls and connect_tokens. Both require that you get permission from the owner of the email account you are adding. The details on creating a user through the API can be found here. Adding a user using connect_tokens is described in the next section.

Connect Tokens

With connect tokens we guide your users through the authentication process. They'll be familiar with the UX flow since it's very similar to how social media apps get authentication. You give us a callback URL and we give you a redirect url to send your users to us. After we get their permission, we'll redirect them back to your app at your callback url. If you want to 100% control this process, you certainly can by manually adding an account and source. In this guide, we'll focus on connect tokens since they're super easy to use! Some email service providers (like Gmail) don't support 3rd party applications connecting via email/password so you must use Oauth2 or connect_tokens (which uses OAuth2 in the background). Here are some more detailed information about connect tokens.

If you've ever logged onto a site using a "Login with Facebook" button, you've used the same basic idea as connect tokens. In this example, the developer of the site previously registered with Facebook as a trusted entity/developer. When you click the "Login with Facebook" button on their site, you get redirected to Facebook's web site which asks you (if you're logged into Facebook right now) "Are you sure you want application X to do this?". When you answer "Yes", Facebook grants the developer's application access to your Facebook data — in this case, all the site probably cares about is that you authenticated with Facebook, so you must be who you say you are. Facebook also redirected you back to the developer's application.

Note that in the above transaction, you, the user, never gave the developer's website your login credentials to Facebook. Supporting Facebook logins essentially freed the developer of the website from writing authentication/authorization code and maintaining userids and passwords in their own database. It also freed you, the user, from creating yet another id and password. Our API allows us to take this further and not only authenticate the user with their email service provider but then we also request access to their email data so that we can write a meaningful email-related application — all without ever knowing the user's password.

If the simple "Login with Facebook" button flow sounds complicated — it is. There are three parties involved: the end-user, the developer, and Facebook. Trust has to be established between all three parties but due to internet limitations only two parties can talk to each other at a time. As a side-effect of this, there are several redirects and challenges from parties to prove they're talking to another party. This multi-step interchange is sometimes called the "OAuth dance". Now, you don't want all this plumbing exposed to your end-user because that would be a terrible user experience. This is where connect_tokens come in. We do the "OAuth dance" for you to minimize the steps the user has to take to connect their email to your application.

Note we have 2 endpoints for connect tokens. One endpoint creates a new user and connects their first email account in one step, and the other endpoint is used to add additional email accounts to a user that already exists.

In pseudo-code, this is how you would create a new user and attach one of their email accounts to it.

  1. Create a requestb.in (in real life, your application would have its own server/UI for the email service provider to post back to).
  2. POST to lite/connect_tokens passing the email you want to connect as a parameter, including a URL of a page on your webserver that Gmail should redirect back to after authentication has completed.
  3. In the response, paste the callback url into your browser (looks like https://api.context.io/connect/somehash).
  4. The browser should show you the Context.IO UI with developer branding.
  5. Ensure you're logged into the email account already in another tab.
  6. Click "next step" button.
  7. You should be redirected to Gmail's UI which should have a button to "allow access". Press it.
  8. You should now be redirected to the redirect URL you specified in the POST response in #1. The query string should have a hash appended to the URL in #2.
  9. Once the redirect happens on #7, a new user will be created. Performing a get to https://api.context.io/lite/users should show your new user.
  10. Now you, as the developer, can issue API requests using that user/email account combination.

PHP

//create a connect token
$addTokenResponse = $contextIO->addConnectToken(array('callback_url' => 'http://yourcallback.com', 'email' => 'test@gmail.com'));
//get the redirect url from the response, and direct the user to it
$redirectUrl = $addTokenResponse->getDataProperty('browser_redirect_url');
print_r($redirectUrl);

//once the user connects, they will be redirected to the callback url with a contextio_token, which your app should store

RUBY

response = cio.request(:post, "https://api.context.io/lite/connect_tokens", {callback_url: callback_url, email:throwaway_gmail}).body

redirect_url = response['browser_redirect_url']

Fetch Folders

Now that you have your application and 1 or more users with a connected email account, your app can do something meaningful. Let's fetch a list of folders for their account. The documentation for it is http://context.io/docs/lite/users/email_accounts/folders.

PHP

//get a list of users, then pull the user ID for one you want to retrieve messages for
$userListResponse = $contextIO->listusers();
$users = $userListResponse->getData();
$user = $users[0];

//list folders for that user - 0 is an alias for the first email account of that user
$folderListResponse = $contextIO->listEmailAccountFolders($user['id'], '0');
print_r($folderListResponse);

RUBY

folders = cio.request(:get, "https://api.context.io/lite/users/#{id}/email_accounts/0/folders", {}).body

puts
puts "Listing folders"
folders.each {|f| puts f['name']}

Fetch list of Messages

Now that you have a list of folders, let's select a folder and get a list of the most recent messages in it.

PHP

//get list of messages from a folder
$messageListResponse = $contextIO->listMessages($user['id'], array('label' => 0, 'folder' => $folder['name']));
$messages = $messageListResponse->getData();
print_r($messages);

RUBY

messages = cio.request(:get, "https://api.context.io/lite/users/#{id}/email_accounts/0/folders/INBOX/messages", {}).body

puts
puts "Listing message subjects"
messages.each { |m| puts m['subject'] }

Fetch Message

Suppose now you want to fetch a particular message. Using the message_id you can access it like this:

PHP

$messageResponse = $contextIO->getMessage($user['id'],
    array('label' => 0, 'folder' => $folder['name'], 'message_id' => $messages['email_message_id']));
print_r($messageResponse->getData());

RUBY

puts "Fetching message body.. please wait..."
# now we can fill in the :message_id and make the API call
random_message_body = cio.request(:get, "https://api.context.io/lite/users/#{id}/email_accounts/0/folders/INBOX/messages/#{random_message['email_message_id']}/body", {}).body

puts "Printing message body for email with subject \"#{random_message['subject']}\" with email_message_id #{random_message['email_message_id']}"

# message bodies can come in multiple types. most commonly, there are usually
# text/plain and a text/html parts. lets print out the first one's contents
puts random_message_body.first['content']

Set Read Flag

Now that your user has retrieved (and viewed) a message, you probably want to record that fact. By far, the most common flag to set is the "read" flag. This is how we set that bit of metadata:

PHP

$setReadResponse = $contextIO->markRead($user['id'],
    array('label' => 0, 'folder' => $folder['name'], 'message_id' => $messages['email_message_id']));
print_r($setReadResponse->getData());

RUBY

response = cio.
    request(:post, "https://api.context.io/lite/users/#{id}/email_accounts/0/folders/INBOX/messages/#{random_message['email_message_id']}/read", {}).
    body
puts response.inspect

Congratulations! Now you know the basics of working with Lite on Context.IO!

There are many more features in Lite including our killer feature — Webhooks. Essentially, a webhook is a notification from our API into your system when email matching specific criteria hits a folder — most commonly the Inbox. More documentation is located at http://context.io/docs/lite/users/webhooks.

While this start guide is geared towards the Lite API, the concepts can easily be applied to our 2.0 API. The basic difference between the 2.0 and Lite is that 2.0 has some additional endpoints such as threads and contacts.