Skip to content

Instantly share code, notes, and snippets.

@cantino
Last active June 16, 2018 18:28
Show Gist options
  • Select an option

  • Save cantino/d1a63045fbfe5fc55a94 to your computer and use it in GitHub Desktop.

Select an option

Save cantino/d1a63045fbfe5fc55a94 to your computer and use it in GitHub Desktop.
Use google-api-ruby-client with the Google Contacts API
2.1.2 :004 > pp Google::Contacts.new(client).contacts
[{:emails=>{:other=>{:address=>"fake@gmail.com", :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=>"fake@gmail.com"},
...
]
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
@sarafisherman22

Copy link
Copy Markdown

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