From The Blog

Import Gmail Contacts using Ruby on Rails

In the past importing Gmail contacts was a bit of a hassle. One of the previous options was to use the Contacts gem found at RubyForge. However, now...

In the past importing Gmail contacts was a bit of a hassle. One of the previous options was to use the Contacts gem found at RubyForge. However, now that the Google Contacts API has been released, it offers a more secure (and hopefully reliable) way to retrieve contacts. The Contacts API allows redirecting and authenticating users through Google, instead of forcing them enter their Gmail password into a third party application. Here is a quick tutorial to get up and running in ruby on rails with the Gmail Contacts API.

First, you need to register your domain with Google. This can be as easy as uploading a temporary file to your domain’s root directory to verify control of the domain. The steps for doing this are clearly outlined at Registration for Web-Based Applications.

Once you’ve verified control of the domain with google, start making your requests! Grabbing the contacts is essentially a three step process:

  • Initiate the authentication with Gmail. Send your user over to enter their credentials, after which Google passes back an AuthSub token valid for one request.
  • Send back the one-time AuthSub token and exchange it for a long-lived token valid for multiple requests.
  • Use this second token to make requests to the Gmail Contacts API and import user’s Gmail contacts.

    More detailed steps on how Google Authentication process works can be found at Authentication for Web Applications

Now lets visit the three steps above in more detail, and implement importing gmail contacts using ruby on rails!

1. First redirect your users to authenticate with Gmail and request a one-time use AuthSub token.

# initiate authentication w/ gmail
  #
  # create url with url-encoded params to initiate connection with contacts api
  #
  # next - The URL of the page that Google should redirect the user to after authentication.
  # scope - Indicates that the application is requesting a token to access contacts feeds. 
  # secure - Indicates whether the client is requesting a secure token.
  # session - Indicates whether the token returned can be exchanged for a multi-use (session) token.
  #  
  next_param = "http%3A%2F%2Fwww.example.com%2F"
  scope_param = "http%3A%2F%2Fwww.google.com%2Fm8%2Ffeeds%2F"
  secure_param = "0"
  session_param = "1"
  root_url = "https://www.google.com/accounts/AuthSubRequest"
  query_string = "?scope=#{scope_param}&session=#{session_param}&secure=#{secure_param}&next=#{next_param}"
  redirect_to root_url + query_string

2. Trade your single-use token for the all powerful AuthSub session token.

  require 'net/http'
  require 'net/https'
 
  token = params[:token] # received the single-use authsub token, exchange for authsub session token
 
  http = Net::HTTP.new('www.google.com', 443)
  http.use_ssl = true
  path = '/accounts/AuthSubSessionToken'
  headers = {'Authorization' => "AuthSubtoken="#{token}""}
  resp, data = http.get(path, headers)
 
  if resp.code == "200" 
    token = ''
    data.split.each do |str|
      if not (str =~ /Token=/).nil?
        token = str.gsub(/Token=/, '')   
      end
    end
    redirect_to "http://www.example.com/?token=#{token}"
  else  
    redirect_to "http://www.example.com/"
  end

Note: There’s probably a better way to grab the above token from the response, if anyone would like to suggest a refactoring here please feel free . . .

3. Finally, grab your buddies!

# GET http://www.google.com/m8/feeds/contacts/default/base
require 'net/http'
require 'rexml/document'      
 
http = Net::HTTP.new('www.google.com', 80)
# by default Google returns 50? contacts at a time.  Set max-results to very high number
# in order to retrieve more contacts
path = "/m8/feeds/contacts/default/base?max-results=10000"
headers = {'Authorization' => "AuthSubtoken="#{authsub_token}""}
resp, data = http.get(path, headers)
 
# extract the name and email address from the response data
xml = REXML::Document.new(data)
contacts = []
xml.elements.each('//entry') do |entry|
  person = {}
  person['name'] = entry.elements['title'].text
 
  gd_email = entry.elements['gd:email']
  person['email'] = gd_email.attributes['address'] if gd_email
 
  contacts << person
end

Hopefully that should help get you started on the right track. The Google Contacts API allows retrieval of other information besides simply name and email address. I’d be interested in hearing what else is everyone using/doing with this API?

Other Posts That Might Interest You

  1. Proving the Productivity of Ruby on Rails with the Rails Rumble
  2. TDD On The Bleeding Edge With Ruby 1.9.3, Rails 3, RSpec, Cucumber, Autotest, and Factory Girl
  3. Easy PDF Generation with Ruby, Rails, and HTMLDOC

Tags: 

  1. Barry 19. Apr, 2008 at 2:19 am #

    Thanks for this simple howto.

  2. Marko 19. Apr, 2008 at 5:09 pm #

    Thanks, it’s my first encounter with Google’s new APIs and this is very helpful.

    A minor note to others, in the last step you’d need to set:

    authsub_token = params[:token]

  3. Mithun 21. Apr, 2008 at 3:45 am #

    Nice tutorial!

  4. vanderkerkoff 22. Apr, 2008 at 10:19 am #

    good work fella

  5. Tjerk Wolterink 23. Apr, 2008 at 3:55 am #

    For the java developers that visit this website i point to
    http://code.google.com/p/contactlistimporter/
    for an implementation in java.

    The contactlistimporter that i created supports different services for importing contacts.

  6. Mislav 23. Apr, 2008 at 3:30 pm #

    Or, simply use the Google Contacts Data API implemented in Ruby: http://github.com/mislav/contacts/tree/master

  7. Paul M. Watson 27. May, 2008 at 9:32 am #

    Thanks for the info, it really helped.

  8. The Irish Penguin 24. Jun, 2008 at 3:55 pm #

    Hi, thanks for the great article. I’ve just added a few clarifications for newbies on my own site at
    http://www.theirishpenguin.com/2008/06/25/a-little-help-on-importing-gmail-contacts-using-ruby-on-rails

    Thanks again!
    The Irish Penguin

  9. Jason Green 23. Jul, 2008 at 11:44 am #

    Hey, just wondering if you have pluginized this yet?

    Great writeup!

    Jason

  10. Robert Dempsey 23. Jul, 2008 at 2:41 pm #

    Not yet, but that’s a great idea! I’ll let Tom know.

  11. Sonal 19. Sep, 2008 at 6:58 pm #

    Thanks! This is very useful. Following your post, I wrote up a blog entry providing code for securely requesting the token here: http://blog.guitarati.com/2008/08/google-accounts-authentication-using.html

  12. leomayleomay 19. Dec, 2008 at 10:03 pm #

    Hi,
    why I can’t set secure_param to be 1, every time I set this variable to be 1, I get the 403 code. Can anyone help to explain why?

    Thank you.

    BTW, I’ve uploaded a .pem file in “Manager Your Domain”.

    Great article.

  13. Felipe Lopes 06. May, 2009 at 6:16 pm #

    Very nice how-to, congrats

  14. UP 14. Jun, 2009 at 1:44 pm #

    One fix that I needed this to work – you need to remove the outer quotes from around the token parameter.
    Btw, the article by IrishPenguin was superb…helped me understand where to hang off all the code!

    “AuthSubtoken=#{authsub_token}”

  15. UP 14. Jun, 2009 at 1:45 pm #

    I mean “AuthSubtoken=”#{authsub_token}”” –> not working

    “AuthSubtoken=#{authsub_token}” –> working

  16. Maran 14. Aug, 2009 at 7:01 am #

    I’ve wrapped the code up in a few classes and created a demo app for people that wanted to get a head start. No tests or much error exception as of yet but I’ll hopefully worked towards that.

    http://github.com/maran/Gmail-Contacts-Demo/tree/master

  17. danbram 12. Jan, 2010 at 4:58 am #

    Pardon the ignorance Mislav, but how do I register during development? Is there an alternative to make this work while using http:localhost:3000???

Trackbacks/Pingbacks

  1. Import Gmail Contacts using Ruby on Rails | Contacts City - 18. Apr, 2008

    [...] Read the rest of this great post here [...]

  2. links for 2008-04-21 at Topper’s Blog - 20. Apr, 2008

    [...] Import Gmail Contacts using Ruby on Rails | Atlantic Dominion Solutions (tags: google api howto tutorials) [...]

  3. Import Gmail Contacts using Ruby on Rails | Atlantic Dominion Solutions - 21. Apr, 2008

    [...] Go! the coyote says Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages. [...]

  4. roScripts - Webmaster resources and websites - 21. Apr, 2008

    Import Gmail Contacts using Ruby on Rails | Atlantic Dominion Solutions…

    Need help with your ruby programming project Atlantic Dominion Solutions s developers can ensure you maximize your web programming technology with Ruby…

  5. This Week in Ruby (April 21, 2008) | Zen and the Art of Programming - 21. Apr, 2008

    [...] week two must-read, hands-on posts were published: Import Gmail Contacts using Ruby on Rails and Paperclip: Attaching Files in Rails. Both cover tasks that are extremely common and useful for [...]

  6. links for 2008-04-21 « Brent Sordyl’s Blog - 21. Apr, 2008

    [...] Google Contacts API using Ruby on Rails The Google Contacts API has been released, it offers a more secure (and hopefully reliable) way to retrieve contacts. Tutorial on doing so using Ruby on Rails (tags: gmail google api rubyonrails) [...]

  7. Web 2.0 Announcer - 21. Apr, 2008

    Import Gmail Contacts using Ruby on Rails…

    [...]Tutorial on importing Gmail contacts with Ruby on Rails and the new Google Contacts API[...]…

  8. links for 2008-04-21, or so says Harry Love - 21. Apr, 2008

    [...] Import Gmail Contacts using Ruby on Rails | Atlantic Dominion Solutions (tags: ruby rubyonrails gmail google) [...]

  9. links for 2008-04-22 | Libin Pan - 22. Apr, 2008

    [...] Import Gmail Contacts using Ruby on Rails | Atlantic Dominion Solutions Here is a quick tutorial to get up and running in ruby on rails with the Gmail Contacts API. (tags: authentication gmail rails google ruby contacts api rubyonrails programming development) [...]

  10. Web 2.0 Announcer - 23. Apr, 2008

    Import Gmail Contacts using Ruby on Rails | Atlantic Dominion Solutions…

    [...][...]…

  11. Links interessantes — Learning on Rails - 25. Apr, 2008

    [...] Import GMail contacts using Rails [...]

  12. Just imported my first Google Contacts l … « Paul M. Watson - 27. May, 2008

    [...] pm on May 27, 2008 | # | Tags: dev Just imported my first Google Contacts list, nice tutorial here. [...]

  13. The Irish Penguin » Blog Archive » A Little Help on Importing Gmail Contacts using Ruby on Rails - 24. Jun, 2008

    [...] came across a fabulous article on getting your RoR app to pull contacts from your Gmail account at Atlantic Domain Solutions: Import Gmail Contacts using Ruby on Rails. Kudos to Atlantic Domain Solutions! This is a really great article. The only slight issue is that [...]

  14. Here are some links on POCO and OAuth P… « Crawlicious - 25. Apr, 2009

    [...] http://code.google.com/apis/accounts/docs/AuthForWebApps.html http://blog.adsdevshop.com/2008/04/18/import-gmail-contacts-using-ruby-on-rails/ http://developer.yahoo.com/oauth/ http://oauth.net/code/ [...]

  15. Making sense of Virgin phone bills - 20. Nov, 2009

    [...] which offer this, but I found it easier to use the Net::HTTP class – with some help from various web [...]

Leave a Reply

blog comments powered by Disqus