Gmail API(via IMAP) In Ruby on Rails – A piece of cake

We often need to read user email messages from Gmail, In this post I will be taking you through how to access user inbox messages from Gmail using gmail_xoauth gem and Ruby Net::IMAP Net library in your Rails application.

I have the sample example file on gist , I would suggest refer this example side by side with this post.

gmail_xoauth allows you to authenticate Gmail IMAP and STMP via OAuth, using the standard Ruby Net libraries. Gmail Platform provides XOAUTH2 mechanism a OAuth 2.0 protocol used for IMAP AUTHENTICATE and SMTP AUTH commands.

Ruby implements Internet Message Access Protocol (IMAP) client functionality in Net::IMAP Net libraries.

Before we start here are some prerequisite,

1) You need to Authorize user via Google using omniauth-google-oauth2 with omniauth configuration specified in sample omniauth_config.rb

2) While Authorize you must define following scopes.

 scope: "email, profile, https://mail.google.com/" 

3) If you are accessing user email in offline mode then you need to ask user for offline access permissions, to do this you need to specify

 prompt: "consent" #In omniauth configuration 

4) User Access Token provided by Google have limited life time so you must implement a token refresh mechanism to have uninterrupted calls to API’s.

After having above prerequisites in place you can proceed further.

Now, lets read the email message from users gmail inbox

  imap = Net::IMAP.new('imap.gmail.com', 993, usessl = true, certs = nil, verify = false)
  imap.authenticate('XOAUTH2', email, access_token)
  imap.select("[Gmail]/All Mail")

Code explanation, first two lines makes authorization call to ‘imap.gmail.com’, imap.authenticate method takes three parameters ‘XOAUTH2′(the auth type) , user email and user access token which got from OAuth hash after authorizing via omniauth

Response of line imap.authenticate(‘XOAUTH2’, email, access_token), should be

#<struct Net::IMAP::TaggedResponse
tag="RUBY0001",
name="OK",
data=
#<struct Net::IMAP::ResponseText
code=nil,
text="user@email.com authenticated (Success)">,
raw_data="RUBY0001 OK user@email.com authenticated (Success)\r\n">

Here, imap.select selects the specified Gmail Inbox labels, In this case we are selecting ‘[Gmail]/All Mail’ you can select various labels after retrieving all the mailbox labels by list method as

 imap.list("", "*") #Takes two arguments: refname(base directory) and wildcards like '*' or '%'

Response is the array of Net::IMAP::MailboxList which will look like

[#<struct Net::IMAP::MailboxList
attr=[:Hasnochildren],
delim="/",
name="INBOX">,
#<struct Net::IMAP::MailboxList
attr=[:Hasnochildren],
delim="/",
name="[Gmail]/Drafts">]

After selecting specific label(mailbox), you can search email message and read it in envelope format as

  imap.search(["SUBJECT", "hello", "NOT", "NEW"])

This will search for a message having subject ‘hello’ and not a new message, response is the array of message id’s matching this search criteria

  [7293, 7474, 7475, 7476, 7555, 7557, 7558, 7559, 7573, 7675, 7702, 7703, 7796]

Now lets fetch a message envelope by specific message_id

envelope = imap.fetch(7293, "ENVELOPE")

Response will look like

[#<struct Net::IMAP::FetchData
seqno=7293
attr=
{"ENVELOPE"=>
#<struct Net::IMAP::Envelope
date="Tue, 14 Oct 2014 11:02:07 -0400 (EDT)",
subject=
"hello",
from=
[#<struct Net::IMAP::Address
name="hello",
route=nil,
mailbox="inbox",
host="sender.com">],
sender=
[#<struct Net::IMAP::Address
name="hello",
route=nil,
mailbox="inbox",
host="sender.com">],
reply_to=
[#<struct Net::IMAP::Address
name="hello",
route=nil,
mailbox="inbox",
host="sender.com">],
to=
[#<struct Net::IMAP::Address
name=nil,
route=nil,
mailbox="myname",
host="receiver.com">],
cc=nil,
bcc=nil,
in_reply_to=nil,
message_id="<2014101411111.3192989.1484@sailthru.com>">}>]

Kudos!!! that’s it we have successfully retrieved the message from user mailbox.

If you want to implement this feature, I would suggest first go through Net::IMAPgmail_xoauth , XOAUTH2 mechanism and keep practicing and experimenting.

If you got stuck in some problem while implementing this, Please let me know It will be my pleasure to help you out and suggestions are most welcome.

Advertisements

One thought on “Gmail API(via IMAP) In Ruby on Rails – A piece of cake

Add your thoughts...

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.