Last active
June 16, 2018 18:28
-
-
Save cantino/d1a63045fbfe5fc55a94 to your computer and use it in GitHub Desktop.
Use google-api-ruby-client with the Google Contacts API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2.1.2 :004 > pp Google::Contacts.new(client).contacts | |
[{:emails=>{:other=>{:address=>"[email protected]", :primary=>true}}, | |
:phone_numbers=> | |
{:main=>"(555) 123-1234", :home=>"123-123-1234", :mobile=>"555-555-5555"}, | |
:handles=> | |
{:home=>{:address=>"something", :protocol=>"AIM"}, | |
:other=>{:address=>"something-else", :protocol=>"AIM"}}, | |
:nickname=>nil, | |
:websites=>[], | |
:organizations=>[], | |
:events=>[], | |
:birthday=>nil, | |
:addresses=> | |
{:home=> | |
{:formatted_address=>"123 Fake St, New York, NY 12345", | |
:street=>"123 Fake St", | |
:city=>"New York", | |
:region=>"NY", | |
:postcode=>"12345"}}, | |
:name_data=> | |
{:full_name=>"John Smith", | |
:given_name=>"John", | |
:family_name=>"Smith"}, | |
:full_name=>"John Smith", | |
:primary_email=>"[email protected]"}, | |
... | |
] | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Google | |
class Contacts | |
attr_reader :client | |
def initialize(client) | |
@client = client | |
end | |
def execute(options = {}) | |
client.execute({ headers: { 'GData-Version' => '3.0', 'Content-Type' => 'application/json' } }.merge(options)) | |
end | |
def fetch_all(options = {}) | |
execute(uri: "https://www.google.com/m8/feeds/contacts/default/full", | |
parameters: { 'alt' => 'json', | |
'updated-min' => options[:since] || '2011-03-16T00:00:00', | |
'max-results' => '100000' }).data | |
end | |
def contacts | |
fetch_all['feed']['entry'].map do |contact| | |
{ | |
emails: extract_schema(contact['gd$email']), | |
phone_numbers: extract_schema(contact['gd$phoneNumber']), | |
handles: extract_schema(contact['gd$im']), | |
addresses: extract_schema(contact['gd$structuredPostalAddress']), | |
name_data: cleanse_gdata(contact['gd$name']), | |
nickname: contact['gContact$nickname'] && contact['gContact$nickname']['$t'], | |
websites: extract_schema(contact['gContact$website']), | |
organizations: extract_schema(contact['gd$organization']), | |
events: extract_schema(contact['gContact$event']), | |
birthday: contact['gContact$birthday'].try(:[], "when") | |
}.tap do |basic_data| | |
# Extract a few useful bits from the basic data | |
basic_data[:full_name] = basic_data[:name_data].try(:[], :full_name) | |
primary_email_data = basic_data[:emails].find { |type, email| email[:primary] } | |
if primary_email_data | |
basic_data[:primary_email] = primary_email_data.last[:address] | |
end | |
end | |
end | |
end | |
protected | |
# Turn an array of hashes into a hash with keys based on the original hash's 'rel' values, flatten, and cleanse. | |
def extract_schema(records) | |
(records || []).inject({}) do |memo, record| | |
key = (record['rel'] || 'unknown').split('#').last.to_sym | |
value = cleanse_gdata(record.except('rel')) | |
value[:primary] = true if value[:primary] == 'true' # cast to a boolean for primary entries | |
value[:protocol] = value[:protocol].split('#').last if value[:protocol].present? # clean namespace from handle protocols | |
value = value[:$t] if value[:$t].present? # flatten out entries with keys of '$t' | |
value = value[:href] if value.is_a?(Hash) && value.keys == [:href] # flatten out entries with keys of 'href' | |
memo[key] = value | |
memo | |
end | |
end | |
# Transform this | |
# {"gd$fullName"=>{"$t"=>"Bob Smith"}, | |
# "gd$givenName"=>{"$t"=>"Bob"}, | |
# "gd$familyName"=>{"$t"=>"Smith"}} | |
# into this | |
# { :full_name => "Bob Smith", | |
# :given_name => "Bob", | |
# :family_name => "Smith" } | |
def cleanse_gdata(hash) | |
(hash || {}).inject({}) do |m, (k, v)| | |
k = k.gsub(/\Agd\$/, '').underscore # remove leading 'gd$' on key names and switch to underscores | |
v = v['$t'] if v.is_a?(Hash) && v.keys == ['$t'] # flatten out { '$t' => "value" } results | |
m[k.to_sym] = v | |
m | |
end | |
end | |
end | |
end |
Mostly it's just changing client.execute
to client.http
. The format of the call is a little different, but still possible to use the client to make arbitrary HTTP requests.
👍
Thanks for this gist! In case it helps anyone, I've posted an updated gist that works with the 0.9 series of google-api-ruby-client https://gist.github.com/lightman76/2357338dcca65fd390e2 - it also has some additional methods I needed for my purposes to query contacts and retrieve groups.
@lightman76 you are a life saver. Thanks so much for putting this together.
In this example, how do you create client?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Do you know how to do this with new version of the gem?
https://github.com/google/google-api-ruby-client/blob/master/MIGRATING.md
It's not compatible and there is no Contacts API inside
generated/google/apis
... thank you