Skip to content

Instantly share code, notes, and snippets.

@reggieb
Last active December 25, 2015 16:48
Show Gist options
  • Save reggieb/7008094 to your computer and use it in GitHub Desktop.
Save reggieb/7008094 to your computer and use it in GitHub Desktop.
Get a user's google contacts using their valid access token (so they only need to authenticate once)
require "net/http"
require "rexml/document"
class GoogleContactList
attr_reader :token
attr_accessor :response
class << self
def cache
@cache ||= Hash.new
end
def for(token)
cache[token] || new(token).contacts
end
end
def cache(data)
self.class.cache[token] = data
end
def initialize(token)
@token = token
end
def get
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
self.response = http.get(path, headers)
end
def emails
contacts.collect{|contact| contact[:email]}
end
def document
@document ||= REXML::Document.new get.body
end
def contacts
@contacts ||= cache(document.elements.collect('//entry') do |entry|
gd_email = entry.elements['gd:email']
{
name: entry.elements['title'].text,
email: (gd_email.attributes['address'] if gd_email)
}
end)
end
private
def self.uri
@uri ||= URI.parse('https://www.google.com')
end
def self.http
@http ||= Net::HTTP.new(uri.host, uri.port)
end
def http
self.class.http
end
def headers
{
'Authorization' => "AuthSub token=#{token}",
'GData-Version' => '3.0'
}
end
def path
@path ||= '/m8/feeds/contacts/default/full'
end
end
@reggieb
Copy link
Author

reggieb commented Oct 16, 2013

I've used it in a devise omniauth controller, to populate a list of contacts in session:

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def google_oauth2
    # You need to implement the method below in your model (e.g. app/models/user.rb)
    @user = User.find_for_google_oauth2(request.env["omniauth.auth"], current_user)
    logger.info request.env["omniauth.auth"].inspect
    if !@user
      flash[:notice] = 'You are not able to log into this resource'
      redirect_to new_user_session_path
    elsif @user.persisted?
      flash[:notice] = I18n.t "devise.omniauth_callbacks.success", :kind => "Google"
      token = request.env["omniauth.auth"].credentials.token
      session['contacts'] = GoogleContactList.for(token)
      sign_in_and_redirect @user, :event => :authentication
    else
      session["devise.google_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end
end

@reggieb
Copy link
Author

reggieb commented Oct 16, 2013

However, the list of contacts seems fairly random. I think what I actually need is most used contacts which I think I need to access via the google + api and not the google contacts api used here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment